2011-11-25 104 views
40

我试图查询由adium生成的xml文件。 xmlwf表示它的格式良好。通过使用xmllint的调试选项我得到以下内容:xmllint无法正确查询xpath

$ xmllint --debug doc.xml 
DOCUMENT 
version=1.0 
encoding=UTF-8 
URL=doc.xml 
standalone=true 
    ELEMENT chat 
    default namespace href=http://purl.org/net/ulf/ns/0.4-02 
    ATTRIBUTE account 
     TEXT 
     [email protected] 
    ATTRIBUTE service 
     TEXT compact 
     content=MSN 
    TEXT compact 
     content= 
    ELEMENT event 
     ATTRIBUTE type 

一切似乎解析就好。然而,当我试图查询最简单的东西时,我什么也没得到:

$ xmllint --xpath '/chat' doc.xml 
XPath set is empty 

发生了什么?使用xpath运行完全相同的查询会返回正确的结果(但结果之间不会换行)。我做错了什么或者xmllint只是不能正常工作?

这里的XML较短,匿名版本,显示了相同的行为:

<?xml version="1.0" encoding="UTF-8" ?> 
<chat xmlns="http://purl.org/net/ulf/ns/0.4-02" account="[email protected]" service="MSN"> 
<event type="windowOpened" sender="[email protected]" time="2011-11-22T00:34:43-03:00"></event> 
<message sender="[email protected]" time="2011-11-22T00:34:43-03:00" alias="foo"><div><span style="color: #000000; font-family: Helvetica; font-size: 12pt;">hi</span></div></message> 
</chat> 
+0

可以请你分享doc.xml文件 – rpg

回答

67

我不使用xmllint,但我觉得你的XPath不工作的原因是因为你的doc.xml文件正在使用默认名称空间(http://purl.org/net/ulf/ns/0.4-02)。

从我所看到的,你有2个选项。

答:在shell模式下使用xmllint并使用前缀声明命名空间。然后,您可以在XPath中使用该前缀。

xmllint --shell doc.xml 
    /> setns x=http://purl.org/net/ulf/ns/0.4-02 
    /> xpath /x:chat

B.使用local-name()匹配元素名称。

xmllint --xpath /*[local-name()='chat']

你也可以使用具有local-name()沿namespace-uri()='http://purl.org/net/ulf/ns/0.4-02'所以你一定要回到你正打算返回什么。

+2

注意例子A.和B.会失败,如果你不访问根路径,在这种情况下你需要一个双斜线,例如xmllint --xpath“// * [本地名称()= '聊天']”。请参阅http://stackoverflow.com/questions/27311314/how-to-get-the-tag-yweathercondition-from-yahoo-weather-rss-with-xmllint?noredirect=1#comment43085213_27311314 –

+0

@ Avt'W - 此问题/ answer是专门针对xmllint中的命名空间的;没有任何其他XPath主题。什么'/'和'/'匹配是完全不相关的。 –

+5

嘿,这是一个读者的评论,会有一个稍微不同的用例,而不是你的答案的批评者,它准确地回答了问题。有名字空间问题的人可能是新手,因此我认为值得指出。 –