2015-11-19 39 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工具可以更輕鬆地提出你想要的內容。 –