xmllint输出

时间:2015-11-19 17:49:01

标签: xml xpath xmllint

我有一些我想要进行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文档,但是对于更复杂的查询,这种方法是不可能的。

2 个答案:

答案 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]