You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl中使用XML::LibXML的ends-with函数获取XML标签报错求解决

问题分析与解决:XPath ends-with函数未找到错误

问题原因

你使用的ends-with()是XPath 2.0及以上版本才支持的函数,但XML::LibXML默认采用XPath 1.0标准,解析器无法识别该函数,因此抛出"function ends-with not found"错误。


解决方法

提供两种可行的修复方案,按需选择:

方法1:用XPath 1.0语法模拟结尾匹配

在XPath 1.0中,可通过substring()与string-length()的组合实现"匹配字符串结尾"的逻辑,替代ends-with():

原错误XPath表达式:

*[ends-with(name(),"stock")]

替换为等效的XPath 1.0表达式:

*[substring(name(), string-length(name()) - string-length('stock') + 1) = 'stock']

修改后的Perl代码片段:

my $stock_value = $branch->findnodes('*[substring(name(), string-length(name()) - string-length("stock") + 1) = "stock"]')->[0]->textContent;

方法2:用Perl代码直接过滤节点

跳过XPath的字符串匹配逻辑,直接遍历branch下的子节点,用Perl原生的正则匹配判断节点名是否以stock结尾,这种方式更直观且不依赖XPath版本:

完整修改后的代码:

use warnings;
use strict;
use feature 'say';
use Data::Dumper;
use XML::LibXML;

my $file = "ex.xml";
my $parser = XML::LibXML->load_xml(location => $file);
my %branch_stock;

foreach my $sec ($parser->findnodes('/Details/Info')) { 
    for my $branch ($sec->findnodes('./branch')) {
        my $branch_name = $branch->getAttribute('name');
        # 遍历当前branch下的所有子节点
        foreach my $node ($branch->findnodes('*')) {
            my $node_name = $node->nodeName;
            # 正则匹配节点名是否以stock结尾
            if ($node_name =~ /stock$/) {
                $branch_stock{$branch_name} = $node->textContent;
                last; # 找到目标节点后退出循环,避免重复匹配
            }
        }
    }   
}

say Dumper \%branch_stock;

测试结果

两种方法均可正确提取每个branch下的stock相关值,最终输出的哈希结构为:

$VAR1 = {
          'city_1' => '10000',
          'city_2' => '2000',
          'city_3' => '3000'
        };

内容的提问来源于stack exchange,提问作者Perl_Newbie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 15:40:38