ail*_*nlv 49 xml xpath xmllint
我正在尝试查询adium生成的xml文件.xmlwf说它形成得很好.通过使用xmllint的调试选项,我得到以下内容:
$ 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
content=foo@bar.com
ATTRIBUTE service
TEXT compact
content=MSN
TEXT compact
content=
ELEMENT event
ATTRIBUTE type
Run Code Online (Sandbox Code Playgroud)
一切似乎都解析得很好.但是,当我尝试查询最简单的东西时,我什么都得不到:
$ xmllint --xpath '/chat' doc.xml
XPath set is empty
Run Code Online (Sandbox Code Playgroud)
发生了什么?使用xpath运行完全相同的查询会返回正确的结果(但结果之间没有换行符).我做错了什么还是xmllint不能正常工作?
这是一个较短的,匿名的xml版本,它显示了相同的行为:
<?xml version="1.0" encoding="UTF-8" ?>
<chat xmlns="http://purl.org/net/ulf/ns/0.4-02" account="foo@bar.com" service="MSN">
<event type="windowOpened" sender="foo@bar.com" time="2011-11-22T00:34:43-03:00"></event>
<message sender="foo@bar.com" 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>
Run Code Online (Sandbox Code Playgroud)
Dan*_*ley 81
我不使用xmllint,但我认为你的XPath不起作用的原因是你的doc.xml文件使用的是默认的命名空间(http://purl.org/net/ulf/ns/0.4-02).
从我所看到的,你有2个选择.
A.在shell模式下使用xmllint并使用前缀声明命名空间.然后,您可以在XPath中使用该前缀.
xmllint --shell doc.xml
/ > setns x=http://purl.org/net/ulf/ns/0.4-02
/ > xpath /x:chatRun Code Online (Sandbox Code Playgroud)
B.使用local-name()匹配的元素名称.
xmllint --xpath /*[local-name()='chat']Run Code Online (Sandbox Code Playgroud)
您可能还想namespace-uri()='http://purl.org/net/ulf/ns/0.4-02'与之一起使用,local-name()因此您肯定会准确地返回您想要返回的内容.
我意识到这个问题现在已经很老了,但万一它对某人有帮助......
有同样的问题,这是由于 XML 具有命名空间(有时它在 XML 的不同位置重复)。发现在使用 xmllint 之前删除命名空间最简单:
sed -e 's/xmlns="[^"]*"//g' file.xml | xmllint --xpath "..." -
Run Code Online (Sandbox Code Playgroud)
在我的情况下,XML 是 UTF-16,所以我必须先转换为 UTF-8(对于 sed):
iconv -f utf16 -t utf8 file.xml | sed -e 's/encoding="UTF-16"?>/encoding="UTF-8"?>/' | sed -e 's/xmlns="[^"]*"//g' | xmllint --xpath "..." -
Run Code Online (Sandbox Code Playgroud)