我有一些我想要进行xquery操作的xml文档。通过返回与查询匹配的节点,xmllint似乎几乎可以执行我想要的操作。这对我没有帮助,因为这个节点可能存在很多地方,我不知道匹配的位置。
一个非常简单的例子是 xmllint -xpath'// shutdown [text()=“false”]'返回:<shutdown>false</shutdown><shutdown>false</shutdown><shutdown>false</shutdown><shutdown>false</shutdown><shutdown>false</shutdown>
。
这告诉我有匹配的节点但不是哪个节点。是否有一些方法来获取返回节点的实际xpath?我找不到任何东西。
虽然给出的示例也可以在编辑器中使用xml文档,但是对于更复杂的查询,这种方法是不可能的。
答案 0 :(得分:0)
xmllint
支持普通的XPath 1.0是不可能的(当你标记问题时它不支持XQuery!)。 XPath 3.0(以及XQuery 3.0)将支持@dirkk提出的fn:path($element)
。 XPath 1.0只能用于选择整个子树(包括单个元素,文本节点,属性......),但不能从XML文档中创建新结果。
您必须使用更强大的语言(如XQuery或其他任何内容)来进一步处理ancestor-or-self
轴步骤的XPath结果,该步骤包含路径中的所有元素并加入元素名称:
XQuery示例:
string-join(
(
(: root node :)
"",
(: following steps :)
for $step in //path/to/element/ancestor-or-self::*
return name($step)
),
"/"
)
类似地可以使用任意脚本语言执行,我还提出了PHP equivalent in another question,甚至使用特定路径的位置谓词(这可以很容易地从代码中删除)。
答案 1 :(得分:0)
test.xml的内容:
<l0>
<l1>
<l1-1>
<shutdown>true</shutdown>
</l1-1>
<l1-2>
<shutdown>false</shutdown>
</l1-2>
</l1>
<l2>
<l2-1>
<shutdown>false</shutdown>
</l2-1>
</l2></l0>
Shell脚本:
#!/bin/s
xpath="//shutdown[text()='false']"
count=$(echo "xpath ${xpath}" |xmllint --shell test.xml |grep ELEMENT|wc -l)
x=1
while [ $x -lt `expr $count + 1` ]
do
parents=` echo "xpath (${xpath})[${x}]/ancestor::*" | \
xmllint --shell test.xml| \
grep "ELEMENT" |\
sed "s/.*ELEMENT//"|\
sed ':a;N;$!ba;s/\n/ -> /g'`
echo "${parents} -> shutdown(false)[${x}]"
x=`expr $x + 1`
done
<强>结果:强>
l0 -> l1 -> l1-2 -> shutdown(false)[1]
l0 -> l2 -> l2-1 -> shutdown(false)[2]