This is my XML (snippet):
<?xml version="1.0" encoding="utf-8"?> <test> <body label_position="left"> <page number="1"> <itemset name=""> <item name="" id="1" /> <item name="" id="2" label_position="right" /> </itemset> </page> </body> </test>
What I want to do:
Is <item id="1"> the label_position attribute label_position ?
(1) If so, return it.
(2) If not, check the parent node for this attribute.
(3) If the parent has an attribute, return it.
(4) If not, go to step (2). <body> is the “oldest” node to check.
What I tried:
I use simplexml and xpath , and I tried to select <T26> and all its ancestors, and then move up the tree and stop with the first appearance of label_position .
$xml->xpath("//item[@id='1']::ancestors-or-self/@label_position");
produced an invalid expression .
(1) How can I make this expression work?
(2) Can this be done using "xpath-only" - without crossing the tree and searching?
EDIT: thanks to choroba and dirkk, I was able to put it together:
$test = (string)array_reverse($xml->xpath("//item[@id='2']/ancestor-or-self::*/@label_position"))[0];
Explanation: if both the <item> and <body> attributes have an attribute, xpath will return an array with both values, <body> first. In this case, I want to get <item> , therefore array_reverse() .
see its working: http://codepad.viper-7.com/jDPIde
michi source share