|
|
IntroContrary to popular belief, getElementById() (W3 spec, PHP manual entry) does not return the element with the attribute named <em>id</em> by default. According to the DOM specs, getElementById does return the element with an attribute defined as attribute type ID. In HTML (and therefore all HTML DOM implementations in browsers, SVG is another example), this happens to be the attribute named id. But if you want to use getElementById with an arbitrary XML document, you have to define that first. But there's also an easy solution with the recent addition of xml__id support in libxml2, at least if you're in control of the XML documents. Following are different approaches to make getElementById work with your XML documents (the examples are for PHP 5, but the techniques should work with other languages as well) DTDYou can define your ID attributes with a DTD You have to define the ID attribute for every element. And your ID attribute doesn't have to be called id, it can be every valid attribute name. Of course, the DTD definition can also be external. Here's how it's defined in the XHTML 1.0 DTD -> http://www.w3.org/TR/xhtml1/dtds.html#dtdentry_xhtml1-strict.dtd_coreattrs XML SchemaInstead of a DTD, you can also use a XML Schema document. I'm no Schema expert, therefore the following is just a snippet of how it should basically look like. Any additions to it are welcome Relax NGIn Relax NG, you can also define ID attributes with a data-type expression: Also untested. xml:idAs the above scenarios all have their drawbacks (it relies on external definitions of what's an ID and also needs a validating parser), the W3C came up with another approach, the xml:id attribute. The specs are quite short and worth a read for more information about the whole problem. As of version 2.6.9, libxml2 (and therefore PHP) does support the xml:id specs: The ID does have to be a valid NCName, which for example means, that the first letter can't be a number. Addition from discussion on php-xml-dev: XPathIf you can't change the XML document and use xml:id (or adding DTD definitions) or you don't have a validating parser, you can also use XPath for getting elements with an attribute named id (this would also work with @xml:id instead of @id, if you don't have libxml2 2.6.9 installed). This does actually return the element with an attribute named id in contrast to the DTD approach above, which returns the element with the attribute defined as ID. You should be aware of that difference. BenchmarksSee my slides about "XML on Speed" to see some benchmarks with XPath vs. getElementById() : http://php5.bitflux.org/xmlonspeed/slide_21.php More Links
Category:Articles |
GetElementById Pitfalls
(None)
Comments (3)
Sep 30, 2007
Anonymous says:
This page is very helpful, thank you. For the schema, you need to run the comma...This page is very helpful, thank you.
For the schema, you need to run the command:
$boolResult = $DOMDocument->schemaValidate("/root/too/the.xsd");
Dec 28, 2007
Anonymous says:
Thank you very much;Thank you very much;
Jun 30
Anonymous says:
Thanks for this article ... A nice way to implement the XPath variant is to ext...Thanks for this article ...
A nice way to implement the X-Path variant is to extend the DOMDocument class and override getElementById.
looks something like this:
class CustomDOMDocument extends DOMDocument {
public function getElementById($id)
}
Add Comment