这是我的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>
是要检查的“最旧”节点。
我尝试了什么:
我正在使用simplexml
和xpath
,我尝试选择<item>
及其所有祖先,然后向上遍历树,并在第一次出现label_position
时停止。
$xml->xpath("//item[@id='1']::ancestors-or-self/@label_position");
产生了invalid expression
。
(1)如何让这个表达起作用?
(2)这可以用“仅xpath”完成 - 不经过树并进行搜索吗?
编辑:感谢choroba&amp;德克,我能把它放在一起:
$test = (string)array_reverse($xml->xpath("//item[@id='2']/ancestor-or-self::*/@label_position"))[0];
说明:如果<item>
和<body>
都有属性,xpath
将返回包含两个值的数组,<body>
首先。在这种情况下,我想首先获得<item>
,这就是array_reverse()
的原因。
答案 0 :(得分:2)
您应该更加小心XPath语法。表达的正确形式是
//item[@id='1']/ancestor-or-self::*/@label_position
您不能在谓词后使用::
,并且必须在轴后指定::
。
答案 1 :(得分:2)
您的XPath无效。轴步骤必须在元素名称之前,例如类似于axis::node
,而不是相反。
以下内容应该有效。你的逻辑已经是xpath-only,遍历树是完全正常的。
(//item[@id='1']/ancestor-or-self::*/@label_position)[last()]