2

Possible Duplicate:
Simplify PHP DOM XML parsing - how?

Here is my XML (c.xml):

<?xml version="1.0" encoding="utf-8"?>
<root>
    <head>
        <title id="title">Hello</title>
    </head>
</root>

What I do:

$dom = new DOMDocument;

$dom->load('./c.xml');

var_dump($dom->getElementById('title'));die(); // returns NULL

What is the problem here&?

UPD

$dom->validate(); returns DOMDocument::validate(): no DTD found!

Community
  • 1
  • 1
s.webbandit
  • 16,332
  • 16
  • 58
  • 82
  • Can you run `$dom->validate() ` on your code? – Pez Cuckow Sep 06 '12 at 11:17
  • @Gordon is there to use `id` but not `xml:id`? Maybe I should add `xml:ns` or something to the root element? – s.webbandit Sep 06 '12 at 11:29
  • you dont need to add a namespace to use `xml:id`. See the linked dupe for explanations about it and http://codepad.org/Pn8NmcV6 for proof. – Gordon Sep 06 '12 at 11:31
  • I see. So there is no workaround to use exactly `id`, nor `xml:id`? – s.webbandit Sep 06 '12 at 11:37
  • well, this *is* a workaround. The alternative is to have a full fledged DTD or a Schema file or to fetch all the id attributes like if they were regular attributes, e.g. `//@id` and then use `setIdAttribute` on them. – Gordon Sep 06 '12 at 11:39

1 Answers1

11

I think The Manual explains why this may happen

For this function to work, you will need either to set some ID attributes with DOMElement->setIdAttribute() or a DTD which defines an attribute to be of type ID. In the later case, you will need to validate your document with DOMDocument->validate() or DOMDocument->validateOnParse before using this function.

Potential fixes:

  1. Call $dom->validate();, afterwards you can use $dom->getElementById(), regardless of the errors for some reason.
  2. Use XPath if you don't feel like validating:

    $x = new DOMXPath($dom);

    $el = $x->query("//*[@id='title']")->item(0); //Look for id=title

Example of using a custom DTD:

$dtd = '<!ELEMENT note (to,from,heading,body)>
        <!ELEMENT to (#PCDATA)>
        <!ELEMENT from (#PCDATA)>
        <!ELEMENT heading (#PCDATA)>
        <!ELEMENT body (#PCDATA)>';

$systemId = 'data://text/plain;base64,'.base64_encode($dtd);

$creator = new DOMImplementation;
$doctype = $creator->createDocumentType($root, null, $systemId); //Based on your DTD from above
Leigh
  • 12,859
  • 3
  • 39
  • 60
Pez Cuckow
  • 14,048
  • 16
  • 80
  • 130