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

PerL LibXML - InsertAfter / addSibling - perl, libxml2

Sto cercando di aggiungere semplicemente un blocco di codice xml(da parsed_balance_chunk), testando gli effetti del tentativo di aggiungere un figlio e come fratello. Sto giocando con "insertAfter" e "addSibling" e sto testando come inserire il frammento in diverse sezioni dell'xml. Con "insertAfter" (e per questo "insertBefore"), lo aggiunge come ultimo figlio di "C". 1.) Come posso farlo inserire come primo figlio di "C" (cioè prima di "D")? 2.) Con un altro test, come posso ottenere che sia un fratello di "C"? Quando provo "addSibling", viene visualizzato un messaggio che dice "aggiungere frammenti di documento con addSibling non ancora supportato!".

Inoltre, con la definizione di $ frag, se lo definisco al di fuori dell'aspetto foreach, aggiunge solo $ frag al primo nodo (e non alla seconda occorrenza di "C").

Codice:

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);

File di input:

<?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>

File di uscita:

<?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>

risposte:

1 per risposta № 1

Dalla documentazione per 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.

... quindi, se vuoi che sia inserito come il primo primo figlio, dovrai ottenere un handle sul nodo corrente del primo figlio, in questo modo:

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

1 per risposta № 2
#1
$node->insertBefore($frag, $node->firstChild);
#2
$node->parentNode->insertAfter($frag, $node);