Как добавить еще одну информацию об узле в XML-файл - PullRequest
1 голос
/ 21 ноября 2011

Я написал один скрипт, который создает один 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, ноКак я могу назначить или распечатать эти данные в тот же файл ($ все 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");
   }
   }

, но выдает вроде "ожидаемый тег, <<не найден "Можете ли вы помочь мне со скриптом, потому что я очень плохо знаком с Perl. </p>

1 Ответ

1 голос
/ 21 ноября 2011

Вы бы сделали намного лучше, если бы использовали то, что дает вам XML :: LibXML и связанные с ним модули, это очень большой и всеобъемлющий модуль, позволяющий выполнять много операций в несколько строк.

Вы можете использовать синтаксический анализатор для запуска нового документа dom, используя parse_string, для хранения корневого узла, используя 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);

}

Вы должны будете разрешить пространства имен и еще много чего, но это дает один подход для начала.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...