XML::LibXML 在查找具有命名空间的 XML 节点时出现问题

XML::LibXML issue finding XML nodes with a namespace

提问人:Taylor Stevens 提问时间:1/28/2020 最后编辑:ikegamiTaylor Stevens 更新时间:1/31/2020 访问量:625

问:

我正在编写一个 XML 解析器,并且处理链接的程序有问题。我正在尝试解析 XML 层次结构 Settings/Setting,然后 findnode 'Value'。以下是 XML 的示例:

<?xml version='1.0' ?>
<Settings xmlns='http://hme.com/Settings.xsd'>
  <Setting SID="0">
    <Name>Store ID</Name>
    <Value>72</Value>
  </Setting>
  <Setting SID="1">
    <Name>Deprecated</Name>
    <Value>0</Value>
  </Setting>
  <Setting SID="8">
    <Name>Open Store Hours Sunday</Name>
    <Value>25200</Value>
  </Setting>

这是我用来解析 XML 的代码

my $doc = $parser->parse_file($settings_file) or die "Couldn't parse timer settings\n";

#Sunday
for my $reviewer ($doc->findnodes('/Settings/Setting[@SID="8"]')) {
  my ($name) = $reviewer->findnodes('Value');
  $name->removeChildNodes();
  $name->appendText('109800');
}

当我从 XML 文件中删除 时,替换值节点没有问题。一旦我在 XML 中输入链接,代码就会停止工作,并且不会更新 xml 工作表。有没有办法处理这个链接或删除它,以便我可以正确更新文件?xmlns='http://hme.com/Settings.xsd'

xml perl url xml-libxml

评论

0赞 Grant McLean 1/29/2020
您可能会发现我教程中的“使用命名空间”部分很有用。
0赞 Taylor Stevens 1/31/2020
查看您建议的页面,我相信我正在声明命名空间 correcr,但得到一个 .我使用了 xpath 沙箱,并且能够加载我的 xml 并使用查询来查找节点,但是当我尝试代码时没有运气。这就是我声明命名空间的方式XPath error: Undefined namespace prefixmy $xpc = XML::LibXML::XPathContext->new(); $xpc->registerNs('xsd', 'http://hme.com/Settings.xsd');

答:

3赞 ikegami 1/28/2020 #1

您要求查找命名空间为 null 且名称为 的节点。文档中没有这样的节点,因此不会正确返回任何内容。Settingsfindnodes

您想要查找具有命名空间和 name 的节点。您可以使用以下方法实现此目的:http://hme.com/Settings.xsdSettings

my $xpc = XML::LibXML::XPathContext->new();
$xpc->registerNs( s => 'http://hme.com/Settings.xsd' );

for ($xpc->findnodes('/s:Settings/s:Setting[@SID="8"]'), $doc) {
   ...
}
0赞 Taylor Stevens 1/31/2020 #2

我能够使用此代码使其工作。

my $dom = XML::LibXML->load_xml(location => $filename);

my $xpc = XML::LibXML::XPathContext->new($dom);
$xpc->registerNs('xsd',  'http://hme.com/Settings.xsd');

my($match1) = $xpc->findnodes('//xsd:Settings/xsd:Setting[@SID="8"]/xsd:Value');
$match1->removeChildNodes();
$match1->appendText('23400');

评论

0赞 Taylor Stevens 1/31/2020
如果将来有人看到这个并需要帮助,这个工具对我帮助很大。grantm.github.io/perl-libxml-by-example/_static/xpath-sandbox/......
0赞 ikegami 3/25/2023
这与我 3 天前发布的内容相同(除了您通过使用而不是 )。///
0赞 Taylor Stevens 4/13/2023
@ikegami对不起,我让它“变得更糟”,我没有让它与您的代码一起使用。可能是用户错误,我仍在努力学习。
0赞 ikegami 4/13/2023
除了两个地方之外,代码是相同的:1)你使用了而不是作为前缀,但前缀的选择并不重要。2)你用了代替,这是非常昂贵的,无缘无故,它可能导致不正确的结果。xsds///
0赞 Taylor Stevens 4/13/2023
@ikegami我想这是我的错,就像我说的,我今天不是专家,3年前更不是专家。