4

这是我的 XML(片段):

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

我想要完成的事情:
是否设置<item id="1">label_position属性?
(1) 如果是,请退回。
(2) 如果不是,请检查节点的父节点的该属性。
(3) 如果父级有该属性,则返回它。
(4) 如果没有,转步骤(2)。<body>是要检查的“最旧”节点。

我尝试过的:
我正在使用simplexmland xpath,我尝试选择<item>它的所有祖先,然后向上遍历树并在第一次出现label_position.

$xml->xpath("//item[@id='1']::ancestors-or-self/@label_position");

产生了一个invalid expression.

(1) 如何使这个表达式起作用?
(2) 这可以用“xpath-only”来完成吗 - 不遍历树并进行搜索?

编辑:感谢 choroba 和 dirkk,我能够把它放在一起:

$test = (string)array_reverse($xml->xpath("//item[@id='2']/ancestor-or-self::*/@label_position"))[0];

说明:如果两者都具有<item><body>属性,xpath将返回一个具有两个值的数组,第<body>一个。在这种情况下,我想先得到<item>一个,这就是为什么array_reverse().

看到它工作:http ://codepad.viper-7.com/jDPIde

4

2 回答 2

2

您应该更加小心 XPath 语法。你表达的正确形式是

//item[@id='1']/ancestor-or-self::*/@label_position

您不能::在谓词之后使用,并且必须::在轴之后指定。

于 2013-07-08T14:09:32.737 回答
2

您的 XPath 无效。轴步长必须在元素名称之前,例如类似axis::node,而不是相反。

以下应该工作。您的逻辑已经是 xpath-only 并且遍历树完全没问题。

(//item[@id='1']/ancestor-or-self::*/@label_position)[last()]
于 2013-07-08T14:10:03.000 回答