【问题标题】:XPath 1.0: Select nodes with attribute matching attribute of context nodeXPath 1.0:选择与上下文节点属性匹配的节点
【发布时间】:2015-07-09 05:01:03
【问题描述】:

我无法使用 PHP's SimpleXMLIterator 处理 XML 数据。

在迭代一个子树 (/root/entries) 的节点时,我尝试从另一个子树 (/root/entryvalues) 收集相关数据 - 通过 当前节点 的属性匹配目标节点。

因此,我会在 当前节点(“上下文”;标有注释)上使用 XPath,试图从 (/root/entryvalues) 获取那些具有entry parent 与 当前节点具有相同的 name 属性值 ("foo")。

<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>

一个有效的 XPath 2.0 表达式可能类似于 parent::*/following-sibling::entryvalues/entry[@name = current()[@name]],但我没有 XPath 2.0,所以没有 current() 函数。

如何获得这些节点?


供参考,这里是相关的PHP sn-p:

$xml = new \SimpleXMLIterator($xmldata);
foreach ($xml->xpath('//root/entries/entry') as $entry) {

    // ... extract some data from $entry

    $entryvalues = $entry->xpath('???');
    doSomething($entry, $entryvalues);
}

【问题讨论】:

    标签: php xpath xml-parsing


    【解决方案1】:

    该死,在发布后立即发现了明显的问题(尽管我已经敲了几个小时的头并上下搜索了整个互联网):

    通过 PHP 传输 name 属性值。就这么简单。

    就我而言:

    $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);
    }
    

    我的借口是,实际代码更加封装,所以我错过了提供xpath() 的选项,而不是静态字符串。 (不过,我不知道如何仅使用 XPath 1.0 表达式来实现,但如果它可以正常工作,我会很高兴。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-11
      • 1970-01-01
      • 2017-07-12
      • 2013-11-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多