使用xmllint --xpath提取RSS命名空间元素内容遇“XPath set is empty”问题
问题描述
已查阅Stack Overflow相关搜索结果前三页,仍未找到解决方案;第二页之后的问题已不相关。
现有RSS Feed内容如下:
<?xml version="1.0" encoding="utf-8"?> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns="http://purl.org/rss/1.0/"> <channel rdf:about="https://www.myfeed.tld/"> <title>My Feed</title> <link>https://www.myfeed.tld/</link> </channel> <item rdf:about="https://www.myfeed.tld/mypost"> <title><![CDATA[Posting to SO SO Good]]></title> <link>https://www.myfeed.tld/mypost</link> <dc:date>2024-06-19T07:48:00-05:00</dc:date> </item> </rdf:RDF>
需要提取以下元素的文本内容:
<rdf:RDF><channel><title><rdf:RDF><item><title><rdf:RDF><item><dc:date>
尝试了以下指令,但始终提示XPath集合为空:
xmllint --xpath "//*[local-name()='rdf:RDF']/channel/title/text()" feed.rss xmllint --xpath "//*[local-name()='rdf:RDF']/item/title/text()" feed.rss xmllint --xpath "//*[local-name()='rdf:RDF']/item/*[local-name()='dc:date']/text()" feed.rss
解决方案
你的XPath写法存在两处错误:
local-name()仅需匹配标签名称部分,不需要带命名空间前缀,比如rdf:RDF的local-name是RDF而非rdf:RDF;channel、item、title属于默认命名空间http://purl.org/rss/1.0/,必须正确匹配该命名空间。
以下是两种可行的修正方案:
方案一:用local-name匹配所有元素
# 提取channel的title xmllint --xpath "//*[local-name()='RDF']/*[local-name()='channel']/*[local-name()='title']/text()" feed.rss # 提取item的title xmllint --xpath "//*[local-name()='RDF']/*[local-name()='item']/*[local-name()='title']/text()" feed.rss # 提取item的dc:date xmllint --xpath "//*[local-name()='RDF']/*[local-name()='item']/*[local-name()='date' and namespace-uri()='http://purl.org/dc/elements/1.1/']/text()" feed.rss
方案二:声明命名空间(更清晰易读)
xmllint支持通过--namespace参数声明命名空间,可直接使用前缀编写XPath:
# 提取channel的title xmllint --xpath "//rdf:RDF/rss:channel/rss:title/text()" --namespace "rss=http://purl.org/rss/1.0/" --namespace "rdf=http://www.w3.org/1999/02/22-rdf-syntax-ns#" feed.rss # 提取item的title xmllint --xpath "//rdf:RDF/rss:item/rss:title/text()" --namespace "rss=http://purl.org/rss/1.0/" --namespace "rdf=http://www.w3.org/1999/02/22-rdf-syntax-ns#" feed.rss # 提取item的dc:date xmllint --xpath "//rdf:RDF/rss:item/dc:date/text()" --namespace "rss=http://purl.org/rss/1.0/" --namespace "rdf=http://www.w3.org/1999/02/22-rdf-syntax-ns#" --namespace "dc=http://purl.org/dc/elements/1.1/" feed.rss
执行以上命令即可正确提取所需文本内容。
内容的提问来源于stack exchange,提问作者Jesse
相关产品推荐
相关产品推荐

