I'm stuck processing XML data with PHP's SimpleXMLIterator .
While iterating over the nodes of one subtree ( /root/entries
) I try to gather related data from another subtree ( /root/entryvalues
) - matching the target nodes by an attribute of the current node .
Therefore I'd use XPath on the current node ("Context"; marked with a comment), trying to get those entryvalue
nodes from ( /root/entryvalues
) that have an entry
parent with the same name
attribute value ("foo") as the current node .
<root>
<entries>
<entry name="foo"><!-- <- XPath starts here ("Context") -->
<somedata>1234</somedata>
</entry>
<entry name="bar">
<somedata>asdf</somedata>
</entry>
...
</entries>
<somethingUnrelated />
<entryvalues>
<entry name="foo"><!-- <- want to select subnodes of this node -->
<entryvalue name="foo1">
<text>Foo 1</text>
</entryvalue>
...
<entryvalue name="foo-n">
<text>Foo n</text>
</entryvalue>
</entry>
<!-- no "bar" here -->
<entry name="quux">
<entryvalue name="quux1">
<text>Quux 1</text>
</entryvalue>
</entry>
...
</entryvalues>
</root>
A working XPath 2.0 expression could be something like parent::*/following-sibling::entryvalues/entry[@name = current()[@name]]
, but I don't have XPath 2.0, so no current()
function.
How to get those nodes?
For reference, here is the relevant PHP snippet:
$xml = new \SimpleXMLIterator($xmldata);
foreach ($xml->xpath('//root/entries/entry') as $entry) {
// ... extract some data from $entry
$entryvalues = $entry->xpath('???');
doSomething($entry, $entryvalues);
}
Damnit, found the obvious right after posting (in spite having banged my head for hours and searched the whole internet up and down):
Transport the name
attribute value via PHP. Simple as that.
In my case:
$template = 'parent::*/following-sibling::entryvalues/entry[@name = \'%s\']';
$xml = new \SimpleXMLIterator($xmldata);
foreach ($xml->xpath('//root/entries/entry') as $entry) {
// ... extract some data from $entry
$name = (string)$entry->attributes()['name'];
$entryvalues = $entry->xpath(sprintf($template, $name));
doSomething($entry, $entryvalues);
}
To my excuse, the actual code is a little more encapsulated, so I missed the option give xpath()
more than a static string. (Still, I don't know how to do it with an XPath 1.0 expression alone, but I'm happy if it just works™.)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.