如何在不替换原始值的情况下添加/删除xml文件?

如何在不替换原始值的情况下添加/删除xml文件?,xml,perl,Xml,Perl,我想根据用户的输入文件执行添加/删除功能 我有两个文件。一个是用户的输入文件,另一个是原始xml文件。 首先是检查用户的请求ID是否存在于原始配置中。如果存在,它将执行删除功能,如果原始配置文件中没有ID,它将执行添加功能。根据用户的输入文件请求。我开始学习perl脚本。请帮助建议如何对原始配置文件执行添加/删除功能。非常感谢:) 下面是我的用户输入文件 add:L83A:55FIP:11:18: #addfunction:DesignID:ProcessID:registerIDs del:L

我想根据用户的输入文件执行添加/删除功能

我有两个文件。一个是用户的输入文件,另一个是原始xml文件。 首先是检查用户的请求ID是否存在于原始配置中。如果存在,它将执行删除功能,如果原始配置文件中没有ID,它将执行添加功能。根据用户的输入文件请求。我开始学习perl脚本。请帮助建议如何对原始配置文件执行添加/删除功能。非常感谢:)

下面是我的用户输入文件

add:L83A:55FIP:11:18: #addfunction:DesignID:ProcessID:registerIDs
del:L83A:FRP:149:155:194: #deletefunction:DesignID:ProcessID:registerIDs
这是我的原始配置xml文件

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<Sigma>
<Run>
<DESIGN_ID>L83A</DESIGN_ID>
<PROCESS_ID>55FIP</PROCESS_ID>
<RegisterList>
<Register>70</Register>
<Register>155</Register>
</RegisterList>
</Run>
<Run>
<DESIGN_ID>L83A</DESIGN_ID>
<PROCESS_ID>FRP</PROCESS_ID>
<RegisterList>
<Register>141</Register>
<Register>149</Register>
<Register>151</Register>
<Register>152</Register>
<Register>155</Register>
<Register>194</Register>
</RegisterList>
</Run>
</Sigma>

L83A
55FIP
70
155
L83A
玻璃钢
141
149
151
152
155
194
因此,结果应该通过编写xml文件得到

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<Sigma>
<Run>
<DESIGN_ID>L83A</DESIGN_ID>
<PROCESS_ID>55FIP</PROCESS_ID>
<RegisterList>
<Register>70</Register>
<Register>155</Register>
<Register>11</Register>
<Register>18</Register>
</RegisterList>
</Run>
<Run>
<DESIGN_ID>L83A</DESIGN_ID>
<PROCESS_ID>FRP</PROCESS_ID>
<RegisterList>
<Register>141</Register>
<Register>151</Register>
<Register>152</Register>
</RegisterList>
</Run>
</Sigma>

L83A
55FIP
70
155
11
18
L83A
玻璃钢
141
151
152
但我的代码只替换了11和18,而没有添加。并且不能执行删除功能:(

这是我的密码:

use strict;
use warnings;
use XML::Simple;
use Data::Dumper;
use feature 'say';
my $filename = 'new.txt';
my $data;
my $run;
open(FILE, '<', $filename) or die $!;
foreach $run(@{XMLin('sigma_loader.xml')->{Run}})  # see how it looks
{
  $data->{$run->{DESIGN_ID}}->{$run->{PROCESS_ID}} =
  {map { $_ => 1 } @{$run->{RegisterList}->{Register}}};
}
while (<FILE>)
{   my $line = $_;
   chomp $line ;
my ($action,$design_id, $process_id, @register_ids) = split /:/, $line; #split the line with add:design_ID:process_ID:register_ID

if(exists $data->{$design_id})
{
 if (exists $data->{$design_id}->{$process_id})
  {
   my $register_id;
foreach $register_id (@register_ids) {
   if (exists $data->{$design_id}->{$process_id}->{$register_id}) {
    say " $design_id: $register_id - existing register ID";
   }
  else {
   say "  $design_id : $register_id - no existing register ID";
   }
   if($action eq 'add')
   {
    $data->{$design_id}->{$process_id}= {$register_id , '1'};
     print Dumper($data);

   }
   if($action eq 'del')
   {
    my $xml = XMLin('sigma_loader.xml', ForceArray => 1, KeepRoot => 1);
    delete $xml->{DESIGN_ID}[0]{PROCESS_ID}[0]{RegisterList}[0]{Register}{$register_id};
    print XMLout($xml, KeepRoot => 1)
  }
  }
}
 else{
   say "$design_id: doesn't have $process_id";
  }
  }
 else
{
   say "$design_id does't exist in data";
}
}
使用严格;
使用警告;
使用XML::Simple;
使用数据::转储程序;
使用特征“说”;
我的$filename='new.txt';
我的$数据;
我的$run;
打开(文件,不要使用
XML::Simple
),使用适当的XML模块,如。这会产生预期的输出(可能空白差异不大):

!/usr/bin/env perl
使用警告;
严格使用;
使用XML::LibXML;
my$xmlfile='sigma_loader.xml';
my$commandfile='commands.txt';
我的$DEBUG=1;
my$doc=XML::LibXML->load_XML(位置=>$xmlfile);

打开我的$fh,'对于初学者,在运行代码时阅读,我发现错误:在@INC中找不到XML\LibXML.pm。我试图在命令pmt中安装cpan XML::LibLXML。但出现超时错误。是否仍要安装LibXML?:(超时听起来像是网络问题。您在使用什么操作系统?根据这一点,您可以使用系统的包管理器安装模块,例如在Debian/Ubuntu上,
sudo apt get install libxml libxml perl
。如果您是从源安装模块,如通过
cpan
cpadm
,您需要
libxml2
已安装开发包(在Debian/Ubuntu上,
sudo-apt-get-install libxml2-dev
)。我使用的是microsoft windows版本1809(OS build 17763.1158)@Pannphyupway预装了该模块,对于ActivePerl,您应该能够使用
ppm
进行安装。似乎我的网络没有安装此类XML:LibXML:(使用XML::Simple添加/删除的其他方法吗?
#!/usr/bin/env perl
use warnings;
use strict;
use XML::LibXML;

my $xmlfile = 'sigma_loader.xml';
my $commandfile = 'commands.txt';
my $DEBUG = 1;

my $doc = XML::LibXML->load_xml(location => $xmlfile);

open my $fh, '<', $commandfile or die "$commandfile: $!";
while ( my $line = <$fh> ) {
    chomp($line);
    my ($action,$design_id,$proc_id,@register_ids) = split /:/, $line;
    my @runs = $doc->findnodes("/Sigma/Run[DESIGN_ID='$design_id'"
        ." and PROCESS_ID='$proc_id']");
    print STDERR "Found ".@runs." Run nodes matching DESIGN_ID="
        ."$design_id PROCESS_ID=$proc_id\n" if $DEBUG;
    for my $run (@runs) {
        my ($reglist) = $run->findnodes('./RegisterList')
            or die "Failed to find RegisterList";
        my @regs = $reglist->findnodes('./Register['
            .join(' or ', map {"text()='$_'"} @register_ids).']');
        print STDERR "Found ".@regs." Register nodes for IDs "
            .join(',',@register_ids)."\n" if $DEBUG;
        if ($action eq 'add') {
            my %regs = map { $_->textContent => $_ } @regs;
            for my $regid (@register_ids) {
                next if exists $regs{$regid};
                my $reg = $doc->createElement('Register');
                $reg->appendText($regid);
                $reglist->appendChild($reg);
                print STDERR "Added Register $regid\n" if $DEBUG;
            }
        }
        elsif ($action eq 'del') {
            for my $reg (@regs) {
                print STDERR "Removing Register "
                    .$reg->textContent."\n" if $DEBUG;
                $reglist->removeChild($reg);
            }
        }
        else { die "Unknown action '$action'" }
    }
}

print $doc->toString(1);