2015-11-19 108 views
0

我有一些xml文档,我想对其执行xquery操作。 xmllint似乎通过返回与查询相匹配的节点来完成我想要的操作。这并不能帮助我,因为这个节点可能存在很多地方,我不知道匹配的位置。xmllint输出的xpath

一个非常简单的例子是xmllint -xpath '//关机[文本()= “假”]'回报:<shutdown>false</shutdown><shutdown>false</shutdown><shutdown>false</shutdown><shutdown>false</shutdown><shutdown>false</shutdown>

这告诉我有匹配的节点,但不是哪个节点。有没有获得返回节点的实际xpath的方法?我一直无法找到任何东西。

尽管给出的示例也可以在编辑器中对XML文档进行grep处理,但对于更复杂的查询,这种方法是不可能的。

+0

'FN:路径()'(HTTP ://www.w3.org/TR/xp ath-functions-30 /#func-path)是你正在寻找的。但是,这是XQuery 3.0,我不认为xmllint支持它。如果你不必使用这个工具,BaseX和eXist是两个开源的XQuery 3.0处理器。 'basex -q'//关闭[文本()=“false”] /路径()''工作是什么。 – dirkk

+0

谢谢,我会研究这些组件。 – Allpointsw

回答

0

这对于xmllint(它不支持XQuery,因为您标记问题!)支持的普通XPath 1.0是不可能的。 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,另外即使在使用位置谓词针对特定路径(这可以从代码容易地去除再次)。

+0

对不起,XQUERY标签,我只是想它作为一个查询。在将来谈论它时,我一定会保持直言不讳。 – Allpointsw

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] 
+0

谢谢。我试过这个,但显然我们的设备上加载的xmllint没有--shell选项。我需要查看是否可以使用具有该选项的版本加载它。 – Allpointsw

+0

没问题。让我看看我是否可以在没有这个选项的情况下重写它。但如果你可以升级,你会得到一些不错的功能。 –

+0

好的..我能够得到你正在寻找的结果,但它是一个更大的包装程序 - 每次追加/ ..和走上树。这很麻烦和丑陋。如果你需要使用xmllint,那么我认为你需要内置shell的版本。另外,请记住,还有其他命令行XML工具可以更轻松地提出你想要的内容。 –