使用 xmllint 提取多个同名字段
Extract multiple fields same named fields using xmllint
我有一个包含很多媒体字段的 XML 文件。一个例子XML是:
<root>
<item>
<name>Item 1</name>
<mediaList>
<media>
<name>Name 1</name>
<URL><![CDATA[http://example.com/image1.jpg]]></URL>
</media>
<media>
<name>Name 2</name>
<URL><![CDATA[http://example.com/image2.jpg]]></URL>
</media>
</mediaList>
</item>
<item>
<name>Item 2</name>
<mediaList>
<media>
<name>Name 3</name>
<URL><![CDATA[http://example.com/image3.jpg]]></URL>
</media>
<media>
<name>Name 4</name>
<URL><![CDATA[http://example.com/image4.jpg]]></URL>
</media>
</mediaList>
</item>
</root>
所有项目都是以相同的方式构建的。将 XMLLint 与 XPath 结合使用,我试图获取所有 URL 的列表。但是,到目前为止,我还没有找到最好的方法。我尝试过的一些方法是:
xmllint --xpath "string(/root/item/mediaList/URL)" file.xml >> log.txt
这个 returns 不错 URL,但在第一个项目之后就停止了(只给我一张图片)
xmllint --xpath "/root/item/mediaList/URL" file.xml >> log.txt
这给了我所有项目,但所有项目都在同一行上,并且每个项目都显示为 <URL><![CDATA[http://example.com/image.jpg]]></URL>
。
xmllint --xpath "/root/item/mediaList/URL/text()" file.xml >> log.txt
这最接近,但仍然 returns 它周围的 <![CDATA[]]>
标签,并且再次全部排成一行。
我也试过遍历这些项目,但这很慢,而且没有达到应有的效果。
我想要的结果是一个 txt 文件,所有图片都在下面,如下所示:
http://example.com/image1.jpg
http://example.com/image2.jpg
http://example.com/image3.jpg
http://example.com/image4.jpg
我认为你应该更改一个解析器,在 W3C 文档中:
Each character within a CDATA section is treated as character data.
Thus, <![CDATA[<]]> in the source document will treated the same as
<. Both will result in a single < character in a text node in the
tree. Thus, a CDATA section is treated as if the <![CDATA[ and ]]>
were removed and every occurrence of < and & were replaced by < and
& respectively.
CDATA会自动删除,我在python:
测试
tree = etree.fromstring(xml)
tree.xpath('//URL/text()')
输出:
['http://example.com/image1.jpg',
'http://example.com/image2.jpg',
'http://example.com/image3.jpg',
'http://example.com/image4.jpg']
您的 XPath 是正确的。
xmllint
不支持多个 XPath 匹配的 string(...)
。 (因此它只显示第一个结果)。
您可以使用 xmlstarlet
如:
xmlstarlet sel -T -t -m /root/item/mediaList/media/URL -v . -n file.xml
它产生
http://example.com/image1.jpg
http://example.com/image2.jpg
http://example.com/image3.jpg
http://example.com/image4.jpg
或者 perl(安装了 XML::LibXML 模块)如:
perl -MXML::LibXML -E 'say $_->to_literal for XML::LibXML->load_xml(location=>q{file.xml})->findnodes(q{/root/item/mediaList/media/URL})'
也产生与上面相同的结果。
我有一个包含很多媒体字段的 XML 文件。一个例子XML是:
<root>
<item>
<name>Item 1</name>
<mediaList>
<media>
<name>Name 1</name>
<URL><![CDATA[http://example.com/image1.jpg]]></URL>
</media>
<media>
<name>Name 2</name>
<URL><![CDATA[http://example.com/image2.jpg]]></URL>
</media>
</mediaList>
</item>
<item>
<name>Item 2</name>
<mediaList>
<media>
<name>Name 3</name>
<URL><![CDATA[http://example.com/image3.jpg]]></URL>
</media>
<media>
<name>Name 4</name>
<URL><![CDATA[http://example.com/image4.jpg]]></URL>
</media>
</mediaList>
</item>
</root>
所有项目都是以相同的方式构建的。将 XMLLint 与 XPath 结合使用,我试图获取所有 URL 的列表。但是,到目前为止,我还没有找到最好的方法。我尝试过的一些方法是:
xmllint --xpath "string(/root/item/mediaList/URL)" file.xml >> log.txt
这个 returns 不错 URL,但在第一个项目之后就停止了(只给我一张图片)
xmllint --xpath "/root/item/mediaList/URL" file.xml >> log.txt
这给了我所有项目,但所有项目都在同一行上,并且每个项目都显示为 <URL><![CDATA[http://example.com/image.jpg]]></URL>
。
xmllint --xpath "/root/item/mediaList/URL/text()" file.xml >> log.txt
这最接近,但仍然 returns 它周围的 <![CDATA[]]>
标签,并且再次全部排成一行。
我也试过遍历这些项目,但这很慢,而且没有达到应有的效果。
我想要的结果是一个 txt 文件,所有图片都在下面,如下所示:
http://example.com/image1.jpg
http://example.com/image2.jpg
http://example.com/image3.jpg
http://example.com/image4.jpg
我认为你应该更改一个解析器,在 W3C 文档中:
Each character within a CDATA section is treated as character data. Thus, <![CDATA[<]]> in the source document will treated the same as <. Both will result in a single < character in a text node in the tree. Thus, a CDATA section is treated as if the <![CDATA[ and ]]> were removed and every occurrence of < and & were replaced by < and & respectively.
CDATA会自动删除,我在python:
测试tree = etree.fromstring(xml)
tree.xpath('//URL/text()')
输出:
['http://example.com/image1.jpg',
'http://example.com/image2.jpg',
'http://example.com/image3.jpg',
'http://example.com/image4.jpg']
您的 XPath 是正确的。
xmllint
不支持多个 XPath 匹配的 string(...)
。 (因此它只显示第一个结果)。
您可以使用 xmlstarlet
如:
xmlstarlet sel -T -t -m /root/item/mediaList/media/URL -v . -n file.xml
它产生
http://example.com/image1.jpg
http://example.com/image2.jpg
http://example.com/image3.jpg
http://example.com/image4.jpg
或者 perl(安装了 XML::LibXML 模块)如:
perl -MXML::LibXML -E 'say $_->to_literal for XML::LibXML->load_xml(location=>q{file.xml})->findnodes(q{/root/item/mediaList/media/URL})'
也产生与上面相同的结果。