Search code examples
phpxpathsimplexmlxml-namespacescollada

Xpath fails if an element has a a xmlns attribute


Possible Duplicate:
xPath finds nothing but *

Im trying to use xml to parse a .COLLADA file. The problem is I can't seem to use xpath() to access elements if the root tag has a xmlns attribute.

For example this works:

$string = <<<TEST
<?xml version="1.0" encoding="utf-8"?>
<COLLADA version="1.4.1">
  <library_materials>
    <material id="Material" name="Material">
      <instance_effect url="#Material-effect"/>
    </material>
    <material id="Material2" name="Material">
      <instance_effect url="#Material-effect2"/>
    </material>
  </library_materials>
</COLLADA>
TEST;
$lol = new SimpleXMLElement($string);
print_r($lol->library_materials->xpath("material[@id='Material2']"));

But this doesn't:

$string = <<<TEST
<?xml version="1.0" encoding="utf-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
  <library_materials>
    <material id="Material" name="Material">
      <instance_effect url="#Material-effect"/>
    </material>
    <material id="Material2" name="Material">
      <instance_effect url="#Material-effect2"/>
    </material>
  </library_materials>
</COLLADA>
TEST;
$lol = new SimpleXMLElement($string);
print_r($lol->library_materials->xpath("material[@id='Material2']"));

How does the xmlns suddenly make the xml tree unusable? I thought it just defined the namespace so you could tell it apart from other identical tags in other namespaces. What am I missing?


Solution

  • You need to register the namespace:

    $lol = new SimpleXMLElement($string);
    $lol->registerXPathNamespace('cada', 'http://www.collada.org/2005/11/COLLADASchema');
    print_r($lol->xpath("child::cada:library_materials//*[@id='Material2']"));