Core Changes
Bootstrapping
Loading/Parsing/Building
Filters
Error Handling
Validation
Serialization
XPath
of all of the things the W3C has given us, the DOM is probably the one with the least value.
--Michael Brennan on the xml-dev mailing list
DOM Level 0: what was implemented for JavaScript in Netscape 3/IE3
DOM Level 1, a W3C Standard
DOM Level 2, a W3C Standard
Added namespace supoprt
DOM Level 3: Several Working Drafts:
Document Object Model (DOM) Level 3 Core Specification (Proposed Recommendation February 5, 2004)
Document Object Model (DOM) Level 3 Load and Save Specification Version 1.0 (Proposed Recommendation February 5, 2004)
Document Object Model (DOM) Level 3 Validation Specification Version 1.0 (Recommendation, January 27, 2004)
Document Object Model (DOM) Level 3 XPath Specification (Note, February 26, 2004)
Document Object Model (DOM) Level 3 Events Specification Version 1.0 (Note, December 7, 2003)
Document Object Model (DOM) Level 3 Views and Formatting Specification (Note, February 26, 2004)
Document Object Model (DOM) Requirements (Note, February 26, 2004)
DOMUserData
DOMConfig
Node
Document
Text
Element
Attr
Entity
Adds:
I will only show the new members. These will
simply be added to the existing Node
interface.
Java binding:
package org.w3c.dom;
public interface Node {
public String getBaseURI();
public static final short DOCUMENT_POSITION_DISCONNECTED = 0x01;
public static final short DOCUMENT_POSITION_PRECEDING = 0x02;
public static final short DOCUMENT_POSITION_FOLLOWING = 0x04;
public static final short DOCUMENT_POSITION_CONTAINS = 0x08;
public static final short DOCUMENT_POSITION_IS_CONTAINED = 0x10;
public static final short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
public short compareDocumentPosition(Node other) throws DOMException;
public String getTextContent() throws DOMException;
public void setTextContent(String textContent) throws DOMException;
public boolean isSameNode(Node other);
public boolean isEqualNode(Node arg);
public String lookupPrefix(String namespaceURI);
public boolean isDefaultNamespace(String namespaceURI);
public String lookupNamespaceURI(String prefix);
public Node getFeature(String feature, String version);
public Object setUserData(String key, Object data, UserDataHandler handler);
public Object getUserData(String key);
}
A user-defined callback class that is invoked when a node is cloned, imported, deleted, adopted, or renamed
package org.w3c.dom;
public interface UserDataHandler {
// OperationType
public static final short NODE_CLONED = 1;
public static final short NODE_IMPORTED = 2;
public static final short NODE_DELETED = 3;
public static final short NODE_RENAMED = 4;
public static final short NODE_ADOPTED = 5;
public void handle(short operation, String key, Object data, Node src, Node dst);
}
XML documents may be built from multiple parsed entities, each of which is not necessarily a well-formed XML document, but is at least a plausible part of a well-formed XML document.
Each entity may have its own text declaration.
This is like an XML declaration without a standalone
attribute
and with an optional version
attribute:
<?xml version="1.0"?>
<?xml version="1.0" encoding="ISO-8859-9"?>
<?xml encoding="ISO-8859-9"?>
DOM3 adds three read-only properties:
Java binding:
package org.w3c.dom;
public interface Entity extends Node {
public String getInputEncoding();
public String getXmlEncoding();
public String getXmlVersion();
}
Adds:
<?xml version="1.0"?>
<?xml version="1.0" encoding="ISO-8859-9"?>
<?xml version="1.0" encoding="ISO-8859-9" standalone="no"?>
<?xml version="1.0" standalone="yes"?>
adoptNode()
setDocumentURI()
renameNode()
DOMErrorHandler
that will be called in the event "that an error is
encountered while performing an operation on a document"Java binding:
package org.w3c.dom;
public interface Document extends Node {
public String getInputEncoding();
public String getXmlEncoding();
public boolean getXmlStandalone();
public void setXmlStandalone(boolean standalone);
public String getXmlVersion();
public void setXmlVersion(String version);
public boolean getStrictErrorChecking();
public void setStrictErrorChecking(boolean strictErrorChecking);
public Node adoptNode(Node source) throws DOMException;
public DOMErrorHandler getErrorHandler();
public void setErrorHandler(DOMErrorHandler errorHandler);
public String getDocumentURI();
public void setDocumentURI(String documentURI);
public void normalizeDocument();
public Node renameNode(Node n, String namespaceURI, String qualifiedName)
throws DOMException;
public DOMConfiguration getConfig();
}
Maintains a table of boolean, String, and Object parameters such as canonical-form and error-handler
Makes it possible to change what normalizeDocument()
does by modifying these parameters
Java binding:
package org.w3c.dom;
public interface DOMConfiguration {
public void setParameter(String name, Object value) throws DOMException;
public Object getParameter(String name) throws DOMException;
public boolean canSetParameter(String name, Object value);
public DOMStringList getParameterNames();
}
Standard parameters include:
canonical-form
, default false
, optionalcdata-sections
, default true, requiredCDATASection
nodes in the document
check-character-normalization
, default false, optionalcomments
, default trueComment
nodes in the document.
datatype-normalization
, default false, optionalelement-content-whitespace
, default true, optionalentities
, default true, requiredEntityReference
nodes in the
documenterror-handler
, required (non-boolean)DOMErrorHandler
objectinfoset
, default true, requirednamespaces
, default true, optionalnamespace-declarations
, default true, requiredAttr
nodes in the document.normalize-characters
, default false, optionalschema-location
, optionalschema-type
, String, optionalsplit-cdata-sections
, default true, required]]>
validate
, default false, optionalvalidate-if-schema
well-formed
, default true, optionalImplementations may also define their own custom parameters
Adds:
isElementContentWhiteSpace()
wholeText()
Text
nodes logically-adjacent to this node;
i.e. the XPath value of the text nodeJava binding:
package org.w3c.dom;
public interface Text extends Node {
public boolean isElementContentWhiteSpace();
public String getWholeText();
public Text replaceWholeText(String content) throws DOMException;
}
Adds:
schemaTypeInfo
TypeInfo
object
that provides a name and URI for the element's type,
as given in the document's schema.
setIdAttribute
Java binding:
package org.w3c.dom;
public interface Element extends Node {
public TypeInfo getSchemaTypeInfo();
public void setIdAttribute(String name, boolean isId) throws DOMException;
public void setIdAttributeNS(String namespaceURI, String localName, boolean isId) throws DOMException;
public void setIdAttributeNode(Attr idAttr, boolean isId) throws DOMException;
}
Adds:
schemaTypeInfo
TypeInfo
object
that provides a name and URI for the attribute's type,
as given in the document's schema.
isId
Java binding:
package org.w3c.dom;
public interface Attr extends Node {
public TypeInfo getSchemaTypeInfo();
public boolean isId();
}
DOM2 has no implementation-independent means to create
a new Document
object
Implementation-dependent methods tend to be fairly complex. For example, in Xerces-J:
DOMImplementation impl = DOMImplementationImpl.getDOMImplementation();
Document fibonacci = impl.createDocument(null, "Fibonacci_Numbers", null);
Still no language-independent means to create
a new Document
object
Does provide an implementation-independent method for Java only:
DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
DOMImplementation impl = registry.getDOMImplementation("XML");
package org.w3c.dom.bootstrap;
public class DOMImplementationRegistry {
public final static String PROPERTY =
"org.w3c.dom.DOMImplementationSourceList";
public static DOMImplementationRegistry newInstance()
throws ClassNotFoundException, InstantiationException,
IllegalAccessException;
public DOMImplementation getDOMImplementation(String features)
throws ClassNotFoundException,
InstantiationException, IllegalAccessException, ClassCastException;
public DOMImplementationList getDOMImplementationList(String features)
throws ClassNotFoundException,
InstantiationException, IllegalAccessException, ClassCastException;
public void addSource(DOMImplementationSource s)
throws ClassNotFoundException,
InstantiationException, IllegalAccessException;
}
getDOMImplementation()
returns a
DOMImplementation
object that supports the features given in the argument,
or null if no such implementation can be found.
Request a DOMImplementation
that supports XML DOM Level 1, any version of the traversal module, and DOM Level 2 events:
try {
DOMImplementation impl = DOMImplementationRegistry
.getDOMImplementation("XML 1.0 Traversal Events 2.0");
if (impl != null) {
DocumentType svgDOCTYPE = impl.createDocumentType("svg",
"-//W3C//DTD SVG 1.0//EN",
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd");
Document svgDoc = impl.createDocument(
"http://www.w3.org/2000/svg", "svg", svgDOCTYPE
);
// work with the document...
}
}
catch (Exception ex) {
System.out.println(ex);
}
Be sure to check whether the implementation returned is null before using it. Many installations may not be able to support all the features you ask for.
DOMImplementationRegistry
searches for DOMImplementation classes by reading the value of the
org.w3c.dom.DOMImplementationSourceList
Java system property.
This property should contain a white space separated list of DOMImplementationSource
DOMErrorHandler
DOMLocator
Similar to SAX2's ErrorHandler
interface.
A callback interface
An application implements this interface and
then registers it with the setErrorHandler()
method to provide
warnings, errors, and fatal errors.
Java binding:
package org.w3c.dom;
public interface DOMErrorHandler {
public boolean handleError(DOMError error);
}
package org.w3c.dom;
public interface DOMError {
public static final short SEVERITY_WARNING = 0;
public static final short SEVERITY_ERROR = 1;
public static final short SEVERITY_FATAL_ERROR = 2;
public short getSeverity();
public String getMessage();
public String getType();
public Object getRelatedException();
public Object getRelatedData();
public DOMLocator getLocation();
}
Similar to SAX2's Locator
interface.
An application can implement this interface and
then register it with the setLocator()
method to
find out in which line and column and file a given
node appears.
Java binding:
package org.w3c.dom;
public interface DOMLocator {
public int getLineNumber();
public int getColumnNumber();
public int getByteOffset();
public int getUtfOffset();
public Node getRelatedNode();
public String getUri();
}
Loading: parsing an existing XML document
to produce a Document
object
Saving: serializing a Document
object
into a file or onto a stream
Completely implementation dependent in DOM2
Library specific code creates a parser
The parser parses the document and returns a DOM
org.w3c.dom.Document
object.
The entire document is stored in memory.
DOM methods and interfaces are used to extract data from this object
This program parses with Xerces. Other parsers are different.
import org.apache.xerces.parsers.*; import org.w3c.dom.*; import org.xml.sax.*; import java.io.*; public class DOMParserMaker { public static void main(String[] args) { DOMParser parser = new DOMParser(); for (int i = 0; i < args.length; i++) { try { parser.parse(args[i]); Document d = parser.getDocument(); } catch (SAXException ex) { System.err.println(ex); } catch (IOException ex) { System.err.println(ex); } } } }
import javax.xml.parsers.*; // JAXP import org.xml.sax.SAXException; import java.io.IOException; public class JAXPParserMaker { public static void main(String[] args) { if (args.length <= 0) { System.out.println("Usage: java JAXPParserMaker URL"); return; } String document = args[0]; try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder parser = factory.newDocumentBuilder(); parser.parse(document); System.out.println(document + " is well-formed."); } catch (SAXException e) { System.out.println(document + " is not well-formed."); } catch (IOException e) { System.out.println( "Due to an IOException, the parser could not check " + document ); } catch (FactoryConfigurationError e) { // JAXP suffers from excessive brain-damage caused by // intellectual in-breeding at Sun. (Basically the Sun // engineers spend way too much time talking to each other // and not nearly enough time talking to people outside // Sun.) Fortunately, you can happily ignore most of the // JAXP brain damage and not be any the poorer for it. // This, however, is one of the few problems you can't // avoid if you're going to use JAXP at all. // DocumentBuilderFactory.newInstance() should throw a // ClassNotFoundException if it can't locate the factory // class. However, what it does throw is an Error, // specifically a FactoryConfigurationError. Very few // programs are prepared to respond to errors as opposed // to exceptions. You should catch this error in your // JAXP programs as quickly as possible even though the // compiler won't require you to, and you should // never rethrow it or otherwise let it escape from the // method that produced it. System.out.println("Could not locate a factory class"); } catch (ParserConfigurationException e) { System.out.println("Could not locate a JAXP parser"); } } }
import org.w3c.dom.*; import org.w3c.dom.ls.*; import org.w3c.dom.bootstrap.*; public class DOM3ParserMaker { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { System.setProperty(DOMImplementationRegistry.PROPERTY, "org.apache.xerces.dom.DOMImplementationSourceImpl"); DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); DOMImplementation impl = registry.getDOMImplementation("LS-Load"); if (impl == null) { System.err.println("Coudl not locate a DOM3 Parser"); return; } DOMImplementationLS implls = (DOMImplementationLS) impl; LSParser parser = implls.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS , null); for (int i = 0; i < args.length; i++) { try { Document d = parser.parseURI(args[i]); } catch (DOMException ex) { System.err.println(ex); } } } }
DOM level 3 is not turned on by default as of 2.6.1
Download source (and tools) and use Ant target "jars-dom3":
%[xerces-2_6_1]$ source build.sh jars-dom3 Xerces-Java Build System ------------------------ Building with classpath /opt/java/j2sdk1.4.2_03/lib/tools.jar:/opt/java/j2sdk1.4.2_03/lib/classes.zip:./tools/ant.jar:./tools/xml-apis.jar:./tools/xercesImpl.jar:./tools/bin/xjavac.jar Starting Ant... Buildfile: build.xml init: [echo] ---------------- Xerces-J 2.6.1 [1999-2004] --------------- prepare: prepare-common: prepare-src-dom3: [copy] Copying 30 files to /home/tmp/xerces-2_6_1/build/src compile-dom3: [xjavac] Compiling 60 source files to /home/tmp/xerces-2_6_1/build/classes [xjavac] Note: Some input files use or override a deprecated API. [xjavac] Note: Recompile with -deprecation for details. jar-dom3: [jar] Building jar: /home/tmp/xerces-2_6_1/build/dom3-xercesImpl.jar apijar-dom3: [copy] Copying 1 file to /home/tmp/xerces-2_6_1/build [jar] Updating jar: /home/tmp/xerces-2_6_1/build/dom3-xml-apis.jar samples-dom3: [copy] Copying 2 files to /home/tmp/xerces-2_6_1/build/samples [xjavac] Compiling 4 source files to /home/tmp/xerces-2_6_1/build/classes [xjavac] Note: /home/tmp/xerces-2_6_1/build/samples/dom/ASBuilder.java uses or overrides a deprecated API. [xjavac] Note: Recompile with -deprecation for details. sampjar-dom3: [jar] Building jar: /home/tmp/xerces-2_6_1/build/xercesSamples.jar jars-dom3: BUILD SUCCESSFUL Total time: 20 seconds
In Java 1.4, the resulting jars need to be copied to jre/lib/endorsed to override the default DOM2 implementation
When released Java 1.5 is supposed will probably support this by default
DOMImplementationLS
DOMImplementation
that provides the factory
methods for creating the objects
required for loading and saving.LSParser
LSInput
InputSource
LSResourceResolver
LSParserFilter
Element
nodes as
they are being processed during the parsing of a document.
like SAX filters.
LSSerializer
LSSerializerFilter
LSLoadEvent
LSProgressEvent
Factory interface to create new
LSParser
and LSSerializer
implementations.
Java Binding:
package org.w3c.dom.ls;
public interface DOMImplementationLS {
public static final short MODE_SYNCHRONOUS = 1;
public static final short MODE_ASYNCHRONOUS = 2;
public LSParser createLSParser(short mode, String schemaType) throws DOMException;
public LSSerializer createLSSerializer();
public LSInput createLSInput();
public LSOutput createLSOutput();
}
Use the feature "LS" or "LS-Async" to find a
DOMImplementation
object that supports
Load and Save.
Cast the DOMImplementation
object to
DOMImplementationLS
.
System.setProperty(DOMImplementationRegistry.PROPERTY,
"org.apache.xerces.dom.DOMImplementationSourceImpl");
DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
DOMImplementation impl = registry.getDOMImplementation("XML 1.0 LS 3.0");
if (impl != null) {
DOMImplementationLS implls = (DOMImplementationLS) impl;
// ...
}
Provides an implementation-independent
API for parsing XML documents to produce a DOM
Document
object.
Instances are built by the
createLSParser()
method in DOMImplementationLS
.
Java Binding:
package org.w3c.dom.ls;
public interface LSParser {
public DOMConfiguration getDomConfig();
public LSParserFilter getFilter();
public void setFilter(LSParserFilter filter);
public boolean getAsync();
public boolean getBusy();
public Document parse(LSInput input) throws DOMException, LSException;
public Document parseURI(String uri) throws DOMException, LSException;
// ACTION_TYPES
public static final short ACTION_APPEND_AS_CHILDREN = 1;
public static final short ACTION_REPLACE_CHILDREN = 2;
public static final short ACTION_INSERT_BEFORE = 3;
public static final short ACTION_INSERT_AFTER = 4;
public static final short ACTION_REPLACE = 5;
public Node parseWithContext(LSInput input, Node contextArg, short action)
throws DOMException, LSException;
public void abort();
}
Like SAX2's InputSource
class,
this interface is an abstraction of all the different things
(streams, files, byte arrays, sockets, URLs, etc.) from which
an XML document can be read.
Java Binding:
package org.w3c.dom.ls;
public interface LSInput {
public Reader getCharacterStream();
public void setCharacterStream(Reader in);
public InputStream getByteStream();
public void setByteStream(InputStream in);
public String getStringData();
public void setStringData(String stringData);
public String getSystemId();
public void setSystemId(String systemId);
public String getPublicId();
public void setPublicId(String publicId);
public String getBaseURI();
public void setBaseURI(String baseURI);
public String getEncoding();
public void setEncoding(String encoding);
public boolean getCertifiedText(); // known to be in NFC
public void setCertifiedText(boolean certifiedText);
}
An abstraction of all the different things (streams, files, byte arrays, sockets, strings, etc.) to which an XML document can be written
Created by DOMIMplementationLS's createLSOutput()
method
Java Binding:
package org.w3c.dom.ls;
public interface LSOutput {
public Writer getCharacterStream();
public void setCharacterStream(java.io.Writer characterStream);
public OutputStream getByteStream();
public void setByteStream(OutputStream byteStream);
public String getSystemId();
public void setSystemId(String systemId);
public String getEncoding();
public void setEncoding(String encoding);
}
Like SAX2's EntityResolver
interface,
this interface lets applications redirect references to external entities.
Java Binding:
package org.w3c.dom.ls;
public interface LSResourceResolver {
public LSInput resolveResource(String type, String namespaceURI,
String publicID, String systemID, String baseURI);
}
Provides an API for serializing (writing) a DOM document out as a sequence of bytes onto a stream, file, socket, byte array, etc.
Java Binding:
package org.w3c.dom.ls;
public interface LSSerializer {
public DOMConfiguration getDomConfig();
public String getNewLine();
public void setNewLine(String newLine);
public LSSerializerFilter getFilter();
public void setFilter(LSSerializerFilter filter);
public boolean write(Node nodeArg, LSOutput destination) throws LSException;
public boolean writeToURI(Node nodeArg, String uri) throws LSException;
public String writeToString(Node node) throws DOMException, LSException;
}
import java.math.*; import java.io.*; import org.w3c.dom.*; import org.w3c.dom.bootstrap.*; import org.w3c.dom.ls.*; public class FibonacciDOM3 { public static void main(String[] args) throws Exception { System.setProperty(DOMImplementationRegistry.PROPERTY, "org.apache.xerces.dom.DOMImplementationSourceImpl"); DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); DOMImplementation impl = registry.getDOMImplementation("XML 1.0 LS"); if (impl == null) { System.err.println("Oops! Couln't find DOM3 implementation"); return; } Document fibonacci = impl.createDocument(null, "Fibonacci_Numbers", null ); BigInteger low = BigInteger.ZERO; BigInteger high = BigInteger.ONE; Element root = fibonacci.getDocumentElement(); for (int i = 0; i <= 25; i++) { Element number = fibonacci.createElement("fibonacci"); number.setAttribute("index", Integer.toString(i)); Text text = fibonacci.createTextNode(low.toString()); number.appendChild(text); root.appendChild(number); BigInteger temp = high; high = high.add(low); low = temp; } // Now that the document is created we need to *serialize* it DOMImplementationLS implls = (DOMImplementationLS) impl; LSSerializer serializer = implls.createLSSerializer(); LSOutput output = implls.createLSOutput(); output.setByteStream(new FileOutputStream("fibonacci_dom.xml")); serializer.write(fibonacci, output); } }
Lets applications examine nodes as they are being constructed during a parse.
As each node is examined, it may be modified or removed, or parsing may be aborted.
Java Binding:
package org.w3c.dom.ls;
public interface LSParserFilter {
// Constants returned by startElement and acceptNode
public static final short FILTER_ACCEPT = 1;
public static final short FILTER_REJECT = 2;
public static final short FILTER_SKIP = 3;
public static final short FILTER_INTERRUPT = 4;
public short startElement(Element element);
public short acceptNode(Node node);
public int getWhatToShow();
}
Lets applications examine nodes as they are being output.
As each element is examined, it may be modified or removed, or output may be aborted.
Java Binding:
package org.w3c.dom.ls;
public interface LSSerializerFilter extends NodeFilter {
public int getWhatToShow();
}
Validates documents in memory, after the parse
Can determine if a certain modification would leave a document in a valid or invalid state
Schema language independent
Java Binding:
package org.w3c.dom.validation;
public interface DocumentEditVAL extends NodeEditVAL {
public boolean getContinuousValidityChecking();
public void setContinuousValidityChecking(boolean continuousValidityChecking)
throws DOMException, ExceptionVAL, DOMException;
public DOMConfiguration getDomConfig();
public NameList getDefinedElements(String namespaceURI);
public short validateDocument();
}
Java Binding:
package org.w3c.dom.validation;
import org.w3c.dom.Node;
import org.w3c.dom.DOMStringList;
public interface NodeEditVAL {
public static final short VAL_WF = 1;
public static final short VAL_NS_WF = 2;
public static final short VAL_INCOMPLETE = 3;
public static final short VAL_SCHEMA = 4;
// validationState
public static final short VAL_TRUE = 5;
public static final short VAL_FALSE = 6;
public static final short VAL_UNKNOWN = 7;
public String getDefaultValue();
public DOMStringList getEnumeratedValues();
public short canInsertBefore(Node newChild, Node refChild);
public short canRemoveChild(Node oldChild);
public short canReplaceChild(Node newChild, Node oldChild);
public short canAppendChild(Node newChild);
public short nodeValidity(short valType);
}
Java Binding:
package org.w3c.dom.validation;
import org.w3c.dom.Node;
import org.w3c.dom.Attr;
import org.w3c.dom.NameList;
public interface ElementEditVAL extends NodeEditVAL {
// ContentTypeVAL
public static final short VAL_EMPTY_CONTENTTYPE = 1;
public static final short VAL_ANY_CONTENTTYPE = 2;
public static final short VAL_MIXED_CONTENTTYPE = 3;
public static final short VAL_ELEMENTS_CONTENTTYPE = 4;
public static final short VAL_SIMPLE_CONTENTTYPE = 5;
public NameList getAllowedChildren();
public NameList getAllowedFirstChildren();
public NameList getAllowedParents();
public NameList getAllowedNextSiblings();
public NameList getAllowedPreviousSiblings();
public NameList getAllowedAttributes();
public NameList getRequiredAttributes();
public short getContentType();
public short canSetTextContent(String possibleTextContent);
public short canSetAttribute(String name, String value);
public short canSetAttributeNode(Attr attrNode);
public short canSetAttributeNS(String namespaceURI, String qualifiedName, String value);
public short canRemoveAttribute(String attrname);
public short canRemoveAttributeNS(String namespaceURI, String localName);
public short canRemoveAttributeNode(Node attrNode);
public short isElementDefined(String name);
public short isElementDefinedNS(String namespaceURI, String name);
}
Java Binding:
package org.w3c.dom.validation;
public interface CharacterDataEditVAL extends NodeEditVAL {
public short isWhitespaceOnly();
public short canSetData(String arg);
public short canAppendData(String arg);
public short canReplaceData(int offset, int count, String arg) throws DOMException;
public short canInsertData(int offset, String arg) throws DOMException;
public short canDeleteData(int offset, int count) throws DOMException;
}
DOM Level 3 includes an optional XPath module in the org.w3c.dom.xpath
package.
The feature string "XPath" with the version "3.0" tests for the presence of this module. For example,
if (!impl.hasFeature("XPath", "3.0")) {
System.err.println("This DOM implementation does not support XPath");
return;
}
An
XPathEvaluator
object processes an XPath expression
and returns an XPathResult
.
In DOM implementations that support XPath, the same classes that implement
org.w3c.dom.Document
implement XPathEvaluator
.
No special constructor or factory class is required. Just cast the Document
object you want to query to XPathEvaluator
.
Suppose you want to extract the value of the double
element from this document:
<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><double>28657</double></value>
</param>
</params>
</methodResponse>
You need to evaluate the XPath expression string(/methodResponse/params/param/value/double)
Document response;
// Initialize response object by parsing request...
String query = "/methodResponse/params/param/value/double";
if (impl.hasFeature("XPath", "3.0")) {
XPathEvaluator evaluator = (XPathEvaluator) response;
try {
XPathResult index = evaluator.evaluate(query, response,
null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null)
// work with the result...
}
catch (XPathException ex) {
System.err.println(query
+ " is not a correct XPath expression");
}
catch (DOMException ex) {
System.err.println(ex);
}
}
Java Binding:
package org.w3c.dom.xpath;
public interface XPathEvaluator {
public XPathExpression createExpression(String expression, XPathNSResolver resolver)
throws XPathException, DOMException;
public XPathNSResolver createNSResolver(Node nodeResolver);
public Object evaluate(String expression, Node contextNode,
XPathNSResolver resolver, short type, Object result)
throws XPathException, DOMException;
}
What you get fby evaluating an XPath expression
There is an impedance mismatch between strongly typed Java and weakly typed XPath here.
Java Binding:
package org.w3c.dom.xpath;
public interface XPathResult {
public static final short ANY_TYPE = 0;
public static final short NUMBER_TYPE = 1;
public static final short STRING_TYPE = 2;
public static final short BOOLEAN_TYPE = 3;
public static final short UNORDERED_NODE_ITERATOR_TYPE = 4;
public static final short ORDERED_NODE_ITERATOR_TYPE = 5;
public static final short UNORDERED_NODE_SNAPSHOT_TYPE = 6;
public static final short ORDERED_NODE_SNAPSHOT_TYPE = 7;
public static final short ANY_UNORDERED_NODE_TYPE = 8;
public static final short FIRST_ORDERED_NODE_TYPE = 9;
public short getResultType();
public double getNumberValue() throws XPathException;
public String getStringValue() throws XPathException;
public boolean getBooleanValue() throws XPathException;
public Node getSingleNodeValue() throws XPathException;
public boolean getInvalidIteratorState();
public int getSnapshotLength() throws XPathException;
public Node iterateNext() throws XPathException, DOMException;
public Node snapshotItem(int index) throws XPathException;
}
Prefix bindings in the XPath expression are not necessarily the same as the prefix bindings in the document.
Elements in the default namespace must be mapped to a prefix in the XPath expression
The XPathNSResolver
interface provides the necessary bindings.
Java Binding:
package org.w3c.dom.xpath;
public interface XPathNSResolver {
public String lookupNamespaceURI(String prefix);
}
Allows precompilation of expressions
Java Binding:
package org.w3c.dom.xpath;
public interface XPathExpression {
public Object evaluate(Node contextNode, short type, Object result)
throws XPathException, DOMException;
}
Some XPath expressions return namespace nodes, which do not have a representation in DOM:
//*[12]/namespace:node()
DOM XPath adds the XPathNamespace
interface for this purpose:
package org.w3c.dom.xpath;
public interface XPathNamespace extends Node {
public static final short XPATH_NAMESPACE_NODE = 13;
public Element getOwnerElement();
}
Document Object Model (DOM) Level 3 Core Specification Version 1.0: http://www.w3.org/TR/DOM-Level-3-Core
Document Object Model (DOM) Level 3 Validation Specification: http://www.w3.org/TR/DOM-Level-3-Val/
Document Object Model (DOM) Level 3 Load and Save Specification: http://www.w3.org/TR/DOM-Level-3-LS/
Document Object Model (DOM) Requirements: http://www.w3.org/TR/DOM-Requirements/
Document Object Model (DOM) Level 3 Views and Formatting Specification: http://www.w3.org/TR/DOM-Level-3-Views/
Document Object Model (DOM) Level 3 XPath Specification: http://www.w3.org/TR/DOM-Level-3-Events/
Document Object Model (DOM) Level 3 Events Specification: http://www.w3.org/TR/DOM-Level-3-Views/