/ / Perl LibXML - InsertAfter / addSibling - perl, libxml2

Perl LibXML - InsertAfter / addSibling - perl, libxml2

Próbuję po prostu dodać blok kodu XML(z parsed_balance_chunk), testowanie efektów próby dodania dziecka i rodzeństwa. Bawię się zarówno „insertAfter”, jak i „addSibling” i testuję, jak wstawić fragment w różnych sekcjach xml. Dzięki „insertAfter” (i dla tego „insertBefore”) dodaje go jako ostatnie dzieci z „C” 1.) W jaki sposób mogę go wstawić jako pierwsze dziecko „C” (tj. Przed „D”)? 2.) W kolejnym teście, jak mogę sprawić, aby był rodzeństwem „C”? Kiedy próbuję „addSibling”, wypluwa wiadomość „dodawanie fragmentów dokumentów z addSibling jeszcze nieobsługiwanych!”.

Ponadto, z definicją $ frag, jeśli zdefiniuję go poza wyglądem foreach, dodaje on tylko $ frag do pierwszego węzła (a nie do drugiego wystąpienia „C”).

Kod:

use warnings;
use strict;
use XML::LibXML;
use Data::Dumper;

my $parser = XML::LibXML->new({keep_blanks=>(0)});
my $dom = $parser->load_xml(location => "test_in.xml") or die;

my @nodes = $dom->findnodes("//E/../..");

foreach my $node (@nodes)
{
my $frag = $parser->parse_balanced_chunk ("<YY>yyy</YY><ZZ>zz</ZZ>");
$node->insertBefore($frag, undef);
#$node->addSibling($frag);
}

open my $FH, ">", "test_out.xml";
print {$FH} $dom->toString(1);
close ($FH);

Plik wejściowy:

<?xml version="1.0"?>
<TT>
<A>ZAB</A>
<B>ZBW</B>
<C>
<D>
<E>ZSE</E>
<F>ZLC</F>
</D>
</C>
<C>
<D>
<E>one</E>
</D>
</C>
</TT>

Plik wyjściowy:

<?xml version="1.0"?>
<TT>
<A>ZAB</A>
<B>ZBW</B>
<C>
<D>
<E>ZSE</E>
<F>ZLC</F>
</D>
<YY>yyy</YY>
<ZZ>zz</ZZ>
</C>
<C>
<D>
<E>one</E>
</D>
<YY>yyy</YY>
<ZZ>zz</ZZ>
</C>
</TT>

Odpowiedzi:

1 dla odpowiedzi № 1

Z dokumentacji dla XML::LibXML::Node->insertNode($newNode, $refNode):

The method inserts $newNode before $refNode. If $refNode is
undefined, the newNode will be set as the new last child of the
parent node.  This function differs from the DOM L2 specification,
in the case, if the new node is not part of the document, the node
will be imported first, automatically.

... więc jeśli chcesz wstawić go jako nowe pierwsze dziecko, będziesz musiał uzyskać uchwyt na bieżącym pierwszym węźle potomnym, tak jak poniżej

$node->insertBefore($frag, $node->firstChild);

1 dla odpowiedzi nr 2
#1
$node->insertBefore($frag, $node->firstChild);
#2
$node->parentNode->insertAfter($frag, $node);