Checking for Module Support
As a brief refresher (and so you're not constantly flipping back to ), Table 6-1 lists the DOM modules.
Table 6-1. Each module has a specific name used to query a parser for module support
Specification | Module name | Summary of purpose |
---|---|---|
DOM Level 2 Core | XML | Extends the DOM Level 1 specification; deals with basic DOM structures like Element, Attr, Document, etc. |
DOM Level 2 Views | Views | Provides a model for scripts to dynamically update a DOM structure |
DOM Level 2 Events | Events | Defines an event model for programs and scripts to use in working with DOM |
DOM Level 2 Style | CSS | Provides a model for CSS based on the DOM Core and DOM Views specifications |
DOM Level 2 Traversal and Range | Traversal/Range | Defines extensions to the DOM for traversing a document andidentifying the range of content within that document |
DOM Level 2 HTML | HTML | Extends the DOM to provide interfaces for dealing with HTML structures in a DOM format |
DOM Level 3 Core | XML | Expands DOM Level 2 to provide bootstrapping of DOM implementations and support for XML InfoSet |
DOM Level 3 Load & Save | LS | Defines DOM extensions for loading and writing XML documents to a persistent storage mechanism, like a filesystem, in a vendor-neutral manner |
DOM Level 3 Validation | Validation | Allows DOM trees to be validated (in memory) and checked for validity as new Nodes are added to the tree |
DOM parsers are not required to implement these modules, so you need to verify that the features you want to use are supported by your XML parser. The DOMImplementation class provides the hasFeature( ) method for just that purpose, as seen in Example 6-1. You will need to change the name of your vendor's DOMImplementation class, but other than that adjustment, it should work for any parser.
Example Supply the module name and a version to the hasFeature( ) method to see if a particular DOM parser implementation supports a certain module
package javaxml3; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.w3c.dom.DOMImplementation; public class DOMModuleChecker { /** DOM Level 2 Modules */ private static Map module2Map; /** DOM Level 3 Modules */ private static Map module3Map; private static void loadModules( ) { module2Map = new HashMap( ); module3Map = new HashMap( ); // DOM Level 2 module2Map.put("XML", "DOM Level 2 Core"); module2Map.put("Views", "DOM Level 2 Views"); module2Map.put("Events", "DOM Level 2 Events"); module2Map.put("CSS", "DOM Level 2 CSS"); module2Map.put("Traversal", "DOM Level 2 Traversal"); module2Map.put("Range", "DOM Level 2 Range"); module2Map.put("HTML", "DOM Level 2 HTML"); // DOM Level 3 module3Map.put("XML", "DOM Level 3 Core"); module3Map.put("LS", "DOM Level 3 Load & Save"); module3Map.put("Validation", "DOM Level 3 Validation"); } public static void main(String args[]) { if (args.length < 1) { System.err.println("Usage: java javaxml3.DOMModuleChecker " + "[org.w3c.dom.DOMImplementation impl class]"); return; } String vendorImplementationClass = args[0]; loadModules( ); try { DOMImplementation impl = (DOMImplementation)Class.forName(vendorImplementationClass) .newInstance( ); System.out.println("For the DOM implementation class " + vendorImplementationClass + "...\n"); // Check for DOM Level 2 Features for (Iterator i=module2Map.keySet().iterator( ); i.hasNext( ); ) { String name = (String)i.next( ); String description = (String)module2Map.get(name); System.out.print("The " + description + " module is "); if (impl.hasFeature(name, "2.0")) { System.out.println("supported."); } else { System.out.println("not supported."); } } // Check for DOM Level 3 Features for (Iterator i=module3Map.keySet().iterator( ); i.hasNext( ); ) { String name = (String)i.next( ); String description = (String)module3Map.get(name); System.out.print("The " + description + " module is "); if (impl.hasFeature(name, "3.0")) { System.out.println("supported."); } else { System.out.println("not supported."); } } } catch (Exception e) { e.printStackTrace( ); } } } |
Running this program with Xerces 2.6.2 in my classpath, I got the following output:
[bmclaugh:~/code/ch06] java javaxml3.DOMModuleChecker org.apache.xerces.dom.DOMImplementationImpl For the DOM implementation class org.apache.xerces.dom.DOMImplementationImpl... The DOM Level 2 Range module is supported. The DOM Level 2 Traversal module is supported. The DOM Level 2 HTML module is not supported. The DOM Level 2 Views module is not supported. The DOM Level 2 Core module is supported. The DOM Level 2 CSS module is not supported. The DOM Level 2 Events module is supported. The DOM Level 3 Validation module is not supported. The DOM Level 3 Core module is supported. The DOM Level 3 Load & Save module is supported.
These results are fairly typical for a well-featured parser. The only real lack of support is in HTML-related modules (HTML, Views, and CSS), as those are largely the domain of parsers like JTidy; working with HTML using a generic parser like Xerces is a real pain. Also note that Xerces supports several of the DOM Level 3 modules, making Xerces a real boon for cutting- and bleeding-edge development work in XML. By specifying the DOMImplementation class for your own vendor, you can check the supported modules in your own DOM parser. This will help ensure you don't start coding for features and modules not present in your parser implementation.
Requesting Feature Support in DOM Level 3
In , I discussed using the DOMImplementationRegistry class to bootstrap a DOM implementation:
DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance( ); DOMImplementation domImpl = registry.getDOMImplementation("XML 3.0"); Document doc = domImpl.createDocument( );
Note that in the getDOMImplementation( ) method, a feature (XML) and version string (3.0) are passed in. This works hand in hand with the getFeature( ) method, allowing you to request a DOMImplementation that has specific module support. So, you could make a request like this:
DOMImplementation domImpl = registry.getDOMImplementation("XML 3.0 +Traversal 2.0");
Here, you're indicating that you need support for DOM Level 3 core, plus the Traversal Level 2 module. You can also omit the version portion of this string, indicating that you will accept any version of support for the specified module:
DOMImplementation domImpl = registry.getDOMImplementation("XML 3.0 +Events");