如何使用Perl LibXML在缺少一个ChildNode的地方添加一个ChildNode?

How to use Perl LibXML to add a ChildNode where one is missing?

提问人:Taylor Stevens 提问时间:4/20/2022 最后编辑:ikegamiTaylor Stevens 更新时间:4/21/2022 访问量:86

问:

我正在使用 libXML 更新一批 XML 设置文件。以下是我尝试更新的 xml 部分的示例:

<Setting SID="2091">
  <Name>HME Cloud User Email</Name>
  <Value/>
</Setting>

我可以使用以下代码正确更新该部分。

#!/usr/bin/perl 

use File::Basename;
use XML::LibXML;
use XML::LibXML::XPathContext; 
 
@files = glob('C:\Users\1025144\Documents\timer_test\*.xml'); 

foreach $file (@files) 
{
    my $dom = XML::LibXML->load_xml(location => $file);
    my $xpc = XML::LibXML::XPathContext->new($dom);
    $xpc->registerNs('xsd',  'http://hme.com/Settings.xsd');
    
    #Add email 
    my($match9) = $xpc->findnodes('//xsd:Settings/xsd:Setting[@SID="2091"]/xsd:Value');
    $match9->removeChildNodes();
    $match9->appendText('[email protected]');
    
    open (OUTFILE, ">$file");               
    print OUTFILE $dom;
}

print "XML Files Updated."

但问题是某些设置文件缺少此 SID 的 Value 节点,请参阅以下示例:

<Setting SID="2091">
  <Name>HME Cloud User Email</Name>
</Setting>

我一直在查看addChild以尝试将节点放入此SID中,但我似乎无法弄清楚语法。我断断续续地使用 perl,所以我希望有人能帮助我弄清楚如何添加这个节点,或者如果 SID 是否具有 Value 节点,我可以使用替代解决方案。

任何帮助都是值得赞赏的 - 谢谢!

xml perl 解析 xml-libxml 子节点

评论


答:

2赞 choroba 4/20/2022 #1

如果 Value 不存在,请使用 创建它。ifaddNewChild

#! /usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

use XML::LibXML;

my @files = @ARGV;

my $uri = 'http://hme.com/Settings.xsd';
for my $file (@files) {
    my $dom = 'XML::LibXML'->load_xml(location => $file);
    my $xpc = 'XML::LibXML::XPathContext'->new($dom);
    $xpc->registerNs('xsd',  $uri);

    if (my ($email) = $xpc->findnodes('//xsd:Settings/xsd:Setting[@SID="2091"]/xsd:Value')) {
        $email->removeChildNodes;
        $email->appendText('[email protected]');
    } else {
        my ($setting) = $xpc->findnodes('//xsd:Settings/xsd:Setting[@SID="2091"]');
        $setting->addNewChild($uri, 'Value')->appendText('[email protected]');
    }

    $dom->toFile("$file.new");
}

say "XML Files Updated."

笔记:

评论

0赞 Taylor Stevens 4/21/2022
效果很好!谢谢。
0赞 ikegami 4/21/2022 #2

如果您将其删除,则不必担心该节点已存在:)

my ( $setting ) = $xpc->findnodes( '//xsd:Settings/xsd:Setting[@SID="2091"]' )
   or die( "Setting not found\n" );

$_->unbindNode() for $xpc->findnodes( 'xsd:Value', $setting );

$setting->addNewChild( $uri, 'Value' )->appendText( '[email protected]' );