如何在xml文件中多添加一个节点信息

发布于 2024-12-17 06:45:10 字数 2561 浏览 0 评论 0原文

我编写了一个脚本,从多个文件创建一个 xml 文件,我编写了这样的脚本。

 #!/usr/bin/perl
 use warnings;
 use strict;
 use XML::LibXML;
 use Carp;
 use File::Find;
 use File::Spec::Functions qw( canonpath );
 use XML::LibXML::Reader;
 use Digest::MD5 'md5';

 if ( @ARGV == 0 ) {
push @ARGV, "c:/main/work";
 warn "Using default path $ARGV[0]\n  Usage: $0  path ...\n";
 }

 open( my $allxml, '>', "all_xml_contents.combined.xml" )
 or die "can't open output xml file for writing: $!\n";
 print $allxml '<?xml version="1.0" encoding="UTF-8"?>',
 "\n<Shiporder xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n";
 my %shipto_md5;
 find(
 sub {
    return unless ( /(_stc\.xml)$/ and -f );
    extract_information();
    return;
 },
 @ARGV
);

print $allxml "</Shiporder>\n";

 sub extract_information {
 my $path = $_;
 if ( my $reader = XML::LibXML::Reader->new( location => $path )) {
    while ( $reader->nextElement( 'data' )) {
        my $elem = $reader->readOuterXml();
        my $md5 = md5( $elem );
        print $allxml $reader->readOuterXml() unless ( $shipto_md5{$md5}++ );
     }
  }
 return;
}

从上面的脚本中,我从所有 xml 文件中提取数据节点信息并将其存储在一个新的 xml 文件中。但我还有一个以“详细信息”开头的节点,我需要提取该信息,并且需要将该信息也添加到文件中,我尝试像这样

$reader->nextElement( 'details' );
    my $information = $reader->readOuterXml();

在 while 循环中添加此信息,但如何将此数据分配或打印到相同的文件($all xml)。请帮我解决这个问题。

在您的建议之后,我尝试了这样的操作,它给出了错误

#!/usr/bin/perl
  use warnings;
  use strict;
  use XML::LibXML;
  use Carp;
  use File::Find;
  use File::Spec::Functions qw( canonpath );
  use XML::LibXML::Reader;
  if ( @ARGV == 0 ) {
  push @ARGV, "V:/main/work";
 warn "Using default path $ARGV[0]\n  Usage: $0  path ...\n";
  }

  my $libXML = new XML::LibXML;
   my $outputDom = $libXML->parse_string('<?xml version="1.0" encoding="UTF-8"?      
   >','<Shiporder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">');
   my $shiporder = $outputDom->documentElement;

  find(
   sub {
    return unless ( /(_stc\.xml)$/ and -f );
    extract_information();
    return;
   },
  @ARGV
  );
 sub extract_information {
   my $path = $_;
 if(my @inputDom = XML::LibXML->load_xml(location => $path)){
 $inputDom->findnodes('//data || //deatils'); 
 foreach (@$inputDom) {
   $shiporder->appendChild($_->parentNode->cloneNode(1)); 
 }
  $outputDom->toFile("allfiles.xml");
   }
   }

,但给出了类似“ '\n\n:1: Parser error:Strat tag Expected,'<'找不到“你能帮我写脚本吗,因为我对 Perl 很陌生。

I written one script that create one xml file from multiple files,I written script like this.

 #!/usr/bin/perl
 use warnings;
 use strict;
 use XML::LibXML;
 use Carp;
 use File::Find;
 use File::Spec::Functions qw( canonpath );
 use XML::LibXML::Reader;
 use Digest::MD5 'md5';

 if ( @ARGV == 0 ) {
push @ARGV, "c:/main/work";
 warn "Using default path $ARGV[0]\n  Usage: $0  path ...\n";
 }

 open( my $allxml, '>', "all_xml_contents.combined.xml" )
 or die "can't open output xml file for writing: $!\n";
 print $allxml '<?xml version="1.0" encoding="UTF-8"?>',
 "\n<Shiporder xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n";
 my %shipto_md5;
 find(
 sub {
    return unless ( /(_stc\.xml)$/ and -f );
    extract_information();
    return;
 },
 @ARGV
);

print $allxml "</Shiporder>\n";

 sub extract_information {
 my $path = $_;
 if ( my $reader = XML::LibXML::Reader->new( location => $path )) {
    while ( $reader->nextElement( 'data' )) {
        my $elem = $reader->readOuterXml();
        my $md5 = md5( $elem );
        print $allxml $reader->readOuterXml() unless ( $shipto_md5{$md5}++ );
     }
  }
 return;
}

from above script I am extracting data node information from all xml files and stored in a new xml file . but I have one more node starts with "details", I need to extract that information and I need to add that information also to the file, I tried like this

$reader->nextElement( 'details' );
    my $information = $reader->readOuterXml();

I added this in while loop but how can I assign or print this data into same file($all xml). Please help me with this problem.

After your suggestion I tried like this, It gives error

#!/usr/bin/perl
  use warnings;
  use strict;
  use XML::LibXML;
  use Carp;
  use File::Find;
  use File::Spec::Functions qw( canonpath );
  use XML::LibXML::Reader;
  if ( @ARGV == 0 ) {
  push @ARGV, "V:/main/work";
 warn "Using default path $ARGV[0]\n  Usage: $0  path ...\n";
  }

  my $libXML = new XML::LibXML;
   my $outputDom = $libXML->parse_string('<?xml version="1.0" encoding="UTF-8"?      
   >','<Shiporder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">');
   my $shiporder = $outputDom->documentElement;

  find(
   sub {
    return unless ( /(_stc\.xml)$/ and -f );
    extract_information();
    return;
   },
  @ARGV
  );
 sub extract_information {
   my $path = $_;
 if(my @inputDom = XML::LibXML->load_xml(location => $path)){
 $inputDom->findnodes('//data || //deatils'); 
 foreach (@$inputDom) {
   $shiporder->appendChild($_->parentNode->cloneNode(1)); 
 }
  $outputDom->toFile("allfiles.xml");
   }
   }

but it gives like " '\n\n:1: Parser error:Strat tag expected,'<' not found " Can you help me with script because I am very new to perl.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

嘿咻 2024-12-24 06:45:10

如果您使用 XML::LibXML 和相关模块为您提供的内容,您会做得更好,它是一个非常大且全面的模块,允许您在几行中完成很多工作。

您可以使用解析器使用 parse_string 启动一个新的 dom 文档,并使用 documentElement 存储根节点。从那里,使用 parse_file 加载每个输入文件,然后在输入文件上查找节点以提取要克隆的节点。然后将输入节点的克隆附加到输出文档,最后使用 toFile 方法写出输出。

像这样的东西:

my $libXML = new XML::LibXML;
my $outputDom = $libXML->parse_string('<?xml version="1.0" encoding="UTF-8"?>',
 '\n<Shiporder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\n');
my $shiporder = $outputDom->documentElement;

...

my $inputDom = $libXML->parse_file(some_file_name);
$inputDom->findnodes('//data || //details'); # use a more suitable xpath
foreach (@$inputDom) {
  $shipOrder->appendChild($_->parentNode->cloneNode(1)); # if you want parent too...
}

...

$outputDom->toFile(some_output_file);

}

你必须允许命名空间之类的东西,但这提供了一种开始的方法。

You would do a lot better if you used what XML::LibXML and related modules gives you, it is a very large and comprehensive module and allows you to do a lot in few lines.

You can use the parser to start a new dom document using parse_string, storing the root node using documentElement. From there, use parse_file to load up each of your input files, then findnodes on the input files to extract the nodes you want to clone. Then append a clone of your input nodes to the output document, and finally use the toFile method to write out your output.

Something like:

my $libXML = new XML::LibXML;
my $outputDom = $libXML->parse_string('<?xml version="1.0" encoding="UTF-8"?>',
 '\n<Shiporder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\n');
my $shiporder = $outputDom->documentElement;

...

my $inputDom = $libXML->parse_file(some_file_name);
$inputDom->findnodes('//data || //details'); # use a more suitable xpath
foreach (@$inputDom) {
  $shipOrder->appendChild($_->parentNode->cloneNode(1)); # if you want parent too...
}

...

$outputDom->toFile(some_output_file);

}

You will have to allow for namespaces and whatnot, but this gives one approach to start with.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文