Почему XML :: LibXML добавляет дочерний элемент к одному <book>, а не к другому? - PullRequest
5 голосов
/ 26 августа 2011

Я вижу странное поведение с XML::LibXML.

Код ниже предназначен для добавления <year>2005</year> к обоим <book> узлам.Здесь что-то не так?Я попытался изменить запрос XPath (//library/book), но результат тот же.

use strict;
use warnings;
use XML::LibXML;

my $xml = XML::LibXML->new->parse_string( << 'MAIN' );
  <library>
    <book>
      <title>Perl Best Practices</title>
      <author>Damian Conway</author>
      <isbn>0596001738</isbn>
      <pages>542</pages>
      <image src="http://www.oreilly.com/catalog/covers/perlbp.s.gif"
             width="145" height="190" />
    </book>
    <book>
      <title>Perl Cookbook, Second Edition</title>
      <author>Tom Christiansen</author>
      <author>Nathan Torkington</author>
      <isbn>0596003137</isbn>
      <pages>964</pages>
      <image src="http://www.oreilly.com/catalog/covers/perlckbk2.s.gif"
             width="145" height="190" />
    </book>
  </library>
MAIN

my ( $age ) = XML::LibXML->new
                ->parse_string( '<year>2005</year>' )
                  ->findnodes( './year' );

my @books = $xml->findnodes( '//book' );

$_->addChild( $age ) for @books;

print $xml->toString;

Вывод

<?xml version="1.0"?>
<library>
    <book>
      <title>Perl Best Practices</title>
      <author>Damian Conway</author>
      <isbn>0596001738</isbn>
      <pages>542</pages>
      <image src="http://www.oreilly.com/catalog/covers/perlbp.s.gif" width="145" height="190"/>
    </book>
    <book>
      <title>Perl Cookbook, Second Edition</title>
      <author>Tom Christiansen</author>
      <author>Nathan Torkington</author>
      <isbn>0596003137</isbn>
      <pages>964</pages>
      <image src="http://www.oreilly.com/catalog/covers/perlckbk2.s.gif" width="145" height="190"/>
    <year>2005</year></book>
  </library>

1 Ответ

12 голосов
/ 26 августа 2011

Добавление узла создает отношения родитель-потомок между узлом и узлом, к которому он добавляется.

Узел не может иметь двух родителей, поэтому при добавлении узла года во вторую книгуон удаляется с первого раза.Вам необходимо создать узел для каждой книги.

for my $book ($xml->findnodes('//book')) {
   my $year = XML::LibXML::Element->new('year');
   $year->appendTextNode('2005');
   $book->addChild($year);
}

или

my $year = XML::LibXML::Element->new('year');
$year->appendTextNode('2005');

for my $book ($xml->findnodes('//book')) {
   $book->addChild( $year->cloneNode(1) );
}
...