xmllint和xpath用于解析来自https://mail.google.com/mail/feed/atom的xml数据

时间:2014-11-25 06:10:07

标签: xml xpath xml-namespaces xmllint

我从我的gmail帐户中获取了一些我要解析的xml数据。 这些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部分)。

- &GT;编辑:感谢@Mathias,正确的在线人员看起来像:     echo&#34; setns x = http://purl.org/atom/ns# \ nxpath / x:feed / x:entry / x:title / text()&#34;

2 个答案:

答案 0 :(得分: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&#34;是在shell模式下使用xmllint,将命名空间与前缀一起注册并在XPath表达式中使用它。有关详细信息,请参阅this answer。这是解决问题的正确方法。

答案 1 :(得分:0)

尝试在shell中为xmllint调试相同的内容:

xmllint --shell filename

xpath '//feed/entry/'

如上所述进行调试,逐层遍历节点,以便您知道它在哪里破解