2014-11-03 143 views
4

今天,我開始學習如何正確使用xmllint。它似乎沒有被很好的覆蓋或解釋。我打算使用單個語言資源文件來運行我的整個系統。我有一個混合的bash腳本和php頁面,必須從這個語言文件中讀取。使用XPATH的Linux Bash XMLLINT

目前我使用以下格式在我的xml文件en.xml:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 

    <item id="index.php"> 
     <label>LABEL</label> 
     <value>VALUE</value> 
     <description>DESCRIPTION</description> 
    </item> 
    <item id="config.php"> 
     <label>LABEL</label> 
     <value>VALUE</value> 
     <description>DESCRIPTION</description> 
    </item> 

</resources> 

現在我要開始一個bash腳本行應該從XML文件中提取數據值。例如,我想從index.php項目獲得DESCRIPTION的值。

我用

xmllint --xpath 'string(//description)' /path/en.xml 

的不同佈局,工作,但現在我改變我的XML文件的佈局,我失去了對如何最好地針對特定<item>,然後向下鑽取到其在bash腳本中的子元素。

有人可以幫助xmllint --xpath線獲得這個值嗎?

回答

6

如何更好地針對特定的,然後向下鑽取到其子元素

正確的XPath表達式來做到這一點:

/resources/item[@id="index.php"]/description/text() 

用簡單的英語:從文件開始節點,轉到文檔元素resources,轉到其子節點item,但僅當id屬性的值爲「index.php」,其子description並檢索其文本v ALUE。

我使用xmllint來驗證XML文檔,但從來沒有用於路徑表達式。在bash shell(至少與Mac OS)有用於評估XPath表達式,被稱爲 「的xpath」 一個更簡單的工具:

$ xpath en.xml '/resources/item[@id="index.php"]/description/text()' 

然後,獲得以下結果:

Found 1 nodes: 
-- NODE -- 
DESCRIPTION 

如果你還是喜歡xmllint,使用下列方式:

$ xmllint --xpath '/resources/item[@id="index.php"]/description/text()' en.xml > result.txt 

默認情況下,--xpath意味着​​,防止xmllint輸出任何內容。將輸出重定向到一個文件。

$ cat result.txt 
DESCRIPTION 
+0

工程。非常感謝你的時間和考慮 – RootWannaBe 2014-11-03 08:20:03

+0

嗨,您使用的是哪個版本的xmllint?我有'xmllint --version xmllint:使用libxml版本20626 編譯時使用:線程樹輸出推式閱讀器模式編寫器SAXv1 FTP HTTP DTDValid HTML舊版C14N目錄XPath XPointer XInclude Iconv ISO8859X Unicode正則表達式自動化Expr架構Schematron模塊調試' t有** - xpath **選項 – 2016-12-22 07:20:34

+0

@ReddySK結果在我用'xmllint:using libxml version 20902'獲得的答案中,但實際上並沒有報告xmllint本身的版本,而是底層庫的版本(最重要的是,libxml)。看起來你有這裏描述的問題:http://stackoverflow.com/q/11975862/1987598,但試圖讓'-xpath'在xmllint中工作是不值得的麻煩:xmllint主要是一個驗證工具,不適用於XPath表達式。改爲使用您選擇的編程語言的XPath庫。 – 2016-12-22 11:49:29

0

幾分鐘前我有同樣的問題,看到這篇文章。

黑客攻擊了一下後,我發現以下解決方案來提取城市:

(wget 'http://maps.googleapis.com/maps/api/geocode/xml?latlng=53.244921,-2.479539&sensor=true' -O dummy.xml -o /dev/null;xmllint --format --xpath '/GeocodeResponse/result[type = "postal_town"]/address_component[type = "postal_town"]/short_name/node()' dummy.xml) 

你的東東來指定正確的x路以獲得所需的XML的標記,然後只返回節點值。

1

我最喜歡的是xmlstarlet,因爲它似乎是更強大的比xmllint

xmlstarlet sel -t -v '/resources/item[@id="index.php"]/description/text()' en.xml 
+0

'xmlstarlet'似乎是一個強大的工具,感謝指針! – 2017-03-22 22:18:35

+0

我對這些命令行祕密武器是'xidel',因爲它支持xpath2.0和xquery。 'xidel'的唯一弱點是它不能從標準輸入讀取,因此它不能像xmlstarlet那樣使用Unix管道。儘管xmlstarlet具有較少的XML功能,但因爲可以管理它而得到補償。 – ifelsemonkey 2017-03-24 21:15:18