使用 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})'

也产生与上面相同的结果。