Here an example PHP and XML code: $XML = <<<XML <items> <item id="123"> <name>Item 1</name> </item> <item id="456"> <name>Item 2</name> </item> <item id="789"> <name>Item 3</name> </item> </items> XML; $objSimpleXML = new SimpleXMLElement($XML); print_r($objSimpleXML->xpath('./item[1]')); print "- - - - - - -\n"; print_r($objSimpleXML->xpath('./item[2][@id]')); print "- - - - - - -\n"; print_r($objSimpleXML->xpath('./item[1]/name')); PHP: I know that I can access the id like this and it works fine: $objSimpleXML->items->item[0]['id'] PHP: But since it is a dynamic application, the xpath is provided at runtime as string. Thus, I must take the xpath approach. The code above produces the following output: Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 123 ) [name] => Item 1 ) ) - - - - - - - Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 456 ) [name] => Item 2 ) ) - - - - - - - Array ( [0] => SimpleXMLElement Object ( ) ) PHP: I agree with the first output. But in the second output the whole element is returned instead of the attribute. Why? And the last listing is empty instead of name content? Why? What would be the correct xpath? My goal for the second and third output is: 456 (just the value of the id-attribute of the second element) Item 1 (just the name of the first element)
// Just name print_r($objSimpleXML->xpath("//item[1]/name")); // Just id print_r($objSimpleXML->xpath("//item[2]/@id")); PHP: OUTPUT: Array ( [0] => SimpleXMLElement Object ( [0] => Item 1 ) ) Array ( [0] => SimpleXMLElement Object ( [@attributes] => Array ( [id] => 456 ) ) ) PHP:
Thanks a lot for the answer. According to documentation // returns ALL elements with this name, meaning that if there is an item element on a deeper level, its value is returned too, which is not desired. Isn't there a more reliable solution? One more question: how do you convert the result to string, especially the second one with the attribute id?
Change it back to ./ and should work as desired. It's in the array so you can just pull it and echo as normal. // Just name $name = $objSimpleXML->xpath("./item[1]/name"); echo $name[0]; // Just id $id = $objSimpleXML->xpath("./item[2]/@id"); echo $id[0]; PHP: If you're really worried about it put (string) in front.
print_r($objSimpleXML->xpath('./item[1]/name')); PHP: returns an empty array, as reported in the original post. If you have another result, what might be the cause? Are there some PHP settings I have to consider?
Doesn't return an empty array for me. <?php $XML = <<<XML <items> <item id="123"> <name>Item 1</name> </item> <item id="456"> <name>Item 2</name> </item> <item id="789"> <name>Item 3</name> </item> </items> XML; $objSimpleXML = new SimpleXMLElement($XML); // Just name $name = $objSimpleXML->xpath("./item[1]/name"); echo $name[0], PHP_EOL; // Just id $id = $objSimpleXML->xpath("./item[2]/@id"); echo $id[0], PHP_EOL; ?> PHP: Also // should not return all item child nodes because you are asking for the first one with [1] so change it back to // and should work also. However for any kind of serious user-based application you'll want to use // and no array key and loop through them using a while statement.