简体   繁体   中英

How to add one more node information to xml file

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM