使用Perl的XML::LibXML解析XML时,无法获取content:encoded节点值?
问题原因及解决方法
你没法获取content:encoded节点内容的核心问题是XML命名空间未正确处理:content:是XML的命名空间前缀,XML::LibXML的XPath查询默认不会识别未注册的前缀,必须先把前缀和对应的命名空间URI绑定,才能正常查询。
下面是两种可行的解决方式:
方法一:使用XML::LibXML::XPathContext(推荐)
先从你的XML文件里找到content前缀对应的命名空间声明(通常在<rss>或<channel>节点上,格式类似xmlns:content="http://purl.org/rss/1.0/modules/content/"),然后通过XPathContext注册这个前缀,再执行查询:
修改后的代码示例:
use XML::LibXML; use XML::LibXML::XPathContext; # 引入XPathContext模块 my $parser = XML::LibXML->new(); print "READING: $this_path/feed_france.xml \n"; my $dom = $parser->parse_file("$this_path/feed_france.xml"); # 注册命名空间前缀 my $xpc = XML::LibXML::XPathContext->new($dom); $xpc->registerNs('content', 'http://purl.org/rss/1.0/modules/content/'); # 替换为你XML里的实际URI # 用XPathContext查询item节点 my @items = $xpc->findnodes('/rss/channel/item'); foreach my $item (@items) { my $title = $item->findvalue('title'); my $company = $item->findvalue('company'); my $pubDate = $item->findvalue('pubDate'); my $summary = $item->findvalue('description'); # 用XPathContext查询带命名空间的节点 my $description = $xpc->findvalue('content:encoded', $item); my $guid = $item->findvalue('guid'); my $link = $item->findvalue('link'); }
方法二:直接通过命名空间URI匹配(无需注册前缀)
如果不想引入XPathContext模块,可以直接在XPath里通过节点的本地名称和命名空间URI来定位,不需要依赖前缀:
# 在循环里替换原来的content:encoded查询 my $description = $item->findvalue('*[local-name()="encoded" and namespace-uri()="http://purl.org/rss/1.0/modules/content/"]');
注意:两种方法里的命名空间URI必须和你XML文件中xmlns:content属性的值完全一致,否则还是查不到节点。
内容的提问来源于stack exchange,提问作者Andrew Newby
相关产品推荐
相关产品推荐

