Is there a way to pass the path to a simplexml node as a variable?
This is what I tried:
//set the path to the node in a variable
$comp = 'component->structuredBody->component';
echo count($xml->component->structuredBody->component); //=== 13
echo count($xml->$comp); //===0
echo count($xml->{$comp});//===0
What you need is XPath, and more specifically SimpleXML's xpath()
method. Instead of traversing using PHP's ->
operator, you would traverse using XPath's /
operator, but otherwise, could achieve exactly the effect you wanted:
$comp = 'component[1]/structuredBody[1]/component';
echo count( $xml->xpath($comp) );
You might think that this could be simplified to 'component/structuredBody/component'
, but that would find all possible paths matching the expression - that is if there are multiple structuredBody
elements, it will search all of them. That might actually be useful, but it is not equivalent to $xml->component->structuredBody->component
, which is actually shorthand for $xml->component[0]->structuredBody[0]->component
.
A few things to note:
- Unlike most operations with SimpleXML, the result is an array, not another SimpleXML object (think of it as a set of search results). It is therefore vital that you check it is not empty before accessing element 0 as an object.
- As you can see in the example above, XPath counts from 1, not 0. I don't know why, but it's caught me out before, so I thought I'd warn you.
- The library SimpleXML is built on supports only XPath 1.0;
examples you see online for XPath 2.0 may not work.
- XPath 1.0 has no notion of a "default namespace", and SimpleXML doesn't automatically register namespace prefixes for use in XPath, so if you're working with namespaces, you need to use
registerXPathNamespace()
.