tags:

views:

43

answers:

3

The javadoc for the Document class has the following note under getElementById.

Note: Attributes with the name "ID" or "id" are not of type ID unless so defined

So, I read an XHTML doc into the DOM (using Xerces 2.9.1).

The doc has a plain old <p id='fribble'> in it.

I call getElementById("fribble"), and it returns null.

I use XPath to get "//*[id='fribble']", and all is well.

So, the question is, what causes the DocumentBuilder to actually mark ID attributes as 'so defined?'

+3  A: 

For the getElementById() call to work, the Document has to know the types of its nodes, and the target node must be of the XML ID type for the method to find it. It knows about the types of its elements via an associated schema. If the schema is not set, or does not declare the id attribute to be of the XML ID type, getElementById() will never find it.

My guess is that your document doesn't know the p element's id attribute is of the XML ID type (is it?). You can navigate to the node in the DOM using getChildNodes() and other DOM-traversal functions, and try calling Attr.isId() on the id attribute to tell for sure.

From the getElementById javadoc:

The DOM implementation is expected to use the attribute Attr.isId to determine if an attribute is of type ID.

Note: Attributes with the name "ID" or "id" are not of type ID unless so defined.

If you are using a DocumentBuilder to parse your XML into a DOM, be sure to call setSchema(schema) on the DocumentBuilderFactory before calling newDocumentBuilder(), to ensure that the builder you get from the factory is aware of element types.

Tom Tresansky
+2  A: 

ID attribute isn't an attribute whose name is "ID", it's an attribute which is declared to be an ID attribute by a DTD or a schema. For example, the html 4 DTD describes it:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
ZloiAdun
+1  A: 

The corresponding xpath expression would actually be id('fribble'), which should return the same result as getElementById. For this to work, the dtd or schema associated with your document has to declare the attribute as being of type ID.

If you are in control of the queried xml you could also try renaming the attribute to xml:id as per http://www.w3.org/TR/xml-id/.

Jörn Horstmann