Search code examples
phpxmlsimplexml

PHP Simple XML Xpath Move Up Tree (Parent with Name)


I am using Xpath with SimpleXML to find child elements like so:

$child=$file->xpath('//w:child')[0];

If I want to select the parent, I can do:

$parent=$child->xpath('..')[0];

But what if I want to find a parent or grandparent called "any_parent", at any level of the tree. For example:

$any_parent=$child->xpath('any_parent//..')[0];

is this possible? I want it to be relative to $child. And then move up the tree and select the tag any_parent. Is there a way to do this?


Solution

  • Yes, this is the ancestor axis.

    You are looking for the element node named any_parent:

    ancestor::any_parent
    

    ^ that is the name of the axis (ancestor, see all), two colons ("::") and the node test, which is here the element name.

    PHP/SimpleXMLElement:

    $any_parent = $child->xpath('ancestor::any_parent')[0];
    

    Note: As there can be none or multiple, directly accessing [0] may give you unexpected results.

    You can provide a default null for example to express not finding any node and the position test to express you want the first node specifically:

    $any_parent = $child->xpath('ancestor::grandparent[1]')[0] ?? null;
    

    or:

    [$any_parent] = $child->xpath('ancestor::grandparent[1]') + [null];