2014-11-25 64 views
1

我從我的gmail帳戶中獲取一些我想分析的xml數據。 THS XML數據的樣子:xmllint和xpath從https://mail.google.com/mail/feed/atom解析xml數據

<?xml version="1.0" encoding="UTF-8"?> 
<feed xmlns="http://purl.org/atom/ns#" version="0.3"> 
    <title>Gmail - Inbox for @gmail.com</title> 
    <tagline>New messages in your Gmail Inbox</tagline> 
    <fullcount>54</fullcount> 
    <link rel="alternate" href="http://mail.google.com/mail" type="text/html"/> 
    <modified>2014-11-25T04:40:04Z</modified> 
    <entry> 
    <title>test</title> 
    <summary/> 
    ... 
</feed> 

和我跳得到所有條目的所有標題的東西,如:

xmllint --xpath '//feed/entry/title' myfile.xml 

現在,我發現,如果有這樣的工作不是這個xmlns信息。 但隨着XMLNS信息,我得到的消息

的XPath設置爲空

我想一個簡單的oneliner來解析該文件,而無需修改文件(去除的xmlns部分)。

- >編輯:由於@Mathias,正確onliner看起來像: 回聲 「setns X = http://purl.org/atom/ns# \ nxpath/X:進料/ X:進入/ X:標題/文本()」

+0

可能重複的[xmllint無法正確查詢與xpath](http://stackoverflow.com/questions/8264134/xmllint-failing-to-properly-query-with-xpath) – 2014-11-25 21:12:09

回答

1

你可能知道,您的輸入XML位於默認名稱空間中。您的原始XPath表達式:

xmllint --xpath '//feed/entry/title' myfile.xml 

永遠不會成功找到名稱空間中的元素。這就是XPath結果集爲空的原因。

如果你絕對不願意登記或申報命名空間,下面的表達式的工作原理:

xmllint --xpath "//*[name() = 'feed']/*[name() = 'entry']/*[name() = 'title']" myfile.xml 

如果輸入XML包含前綴的命名,你必須使用local-name()而不是name()


一種替代方案,是不是「簡單oneliner」是使用在xmllint shell模式,用一個前綴一起寄存器命名空間和在XPath表達式中使用它。詳細信息請參見this answer。這是解決問題的正確方法。

+0

偉大的,在線人完美的作品。爲什麼要使用shell是「正確的方式」? – Jonybegood 2014-11-25 22:09:54

+0

@Jonybegood考慮到XML文檔中的命名空間 - 而不是忽略它們 - 這是正確的方式,它沒有使用正確的方式使用shell。這個xmllint在shell模式下只能這樣做,這只是一個巧合。 – 2014-11-26 08:34:04

+0

謝謝,它非常有意義。我編輯了原始帖子以包含正確的在線解決方案 – Jonybegood 2014-11-30 21:58:08

0

嘗試調試相同的外殼爲xmllint:

xmllint --shell filename 

xpath '//feed/entry/' 

調試像上面,穿越到由級別的節點級別,這樣你會知道它是打破

+0

不是一個非常有用的答案。問題很明顯,元素在一個命名空間中。無需調試。 – 2014-11-25 10:29:23

+0

@MathiasMüller他可以調試自己並找出解決方案,在他上面顯示的代碼示例中,xml是不完整的,我們不能預測該錯誤的位置 – 2014-11-25 11:14:59

+0

如果錯誤是由於文檔不是格式良好的XML導致的,結果不會是'XPath設置爲空'。所以,我們知道XML是「完整的」。另外,在shell模式下,您不得將表達式放在單引號中,否則不會評估路徑表達式。最後,調試只會告訴你完全相同的結果:結果集包含零節點。 – 2014-11-25 11:49:40