简体   繁体   中英

XPath 1.0: Select nodes with attribute matching attribute of context node

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM