2013-01-07 13 views
5

Sto scrivendo un semplice script Perl che utilizza XML :: Smart per creare e analizzare un file XML. Ho avuto un problema con l'eliminazione dei nodi XML. Ho il seguente codice:Perl e XML: Smart: come rimuovere un nodo da un file XML

if (exists $XML->{object}[$n]) { 
    delete $XML->{object}[$n] ; 
}; 
$XML->save('dane.xml') ; 

Si fa quello che ci si aspetta - vale a dire, il nodo corretto viene eliminato. Tuttavia, quando successivamente si tenta di elencare tutti i nodi (bambini di una particolare radice), usando il codice seguente (che di solito funziona):

my @objects = $XML->{object}('@') ; 
foreach my $object (@objects) { 
    say "$object->{address}"; 
}; 

Perl elenca tutti i nodi fino a quello prima di quello eliminato, e poi sputa fuori il seguente errore:

Not a HASH reference at g:/Dwimperl/perl/site/lib/XML/Smart/Tie.pm line 48, <STDIN> line 2. 

stumped - ho provato ad utilizzare varie permutazioni di $ XML> dati(); ma nessuno ha funzionato. Preferirei continuare a utilizzare XML :: Smart per questa attività, quindi spero che questo problema possa essere risolto all'interno di questa particolare libreria.

+2

Buona prima domanda! – slm

+0

+1 Sono d'accordo con slm - questo è rinfrescantemente scritto – Borodin

risposta

3

Mentre XML::Smart è modo migliore di XML::Simple, su cui si basa, a mio parere, è ancora in realtà non molto bravo a rappresentare dati XML . In questo caso devi essere consapevole che il nodo che vuoi eliminare è un elemento di un array Perl, e usando delete su di esso sarà sufficiente impostare l'elemento su undef mentre lo si lascia in posizione (a meno che non si tratti dell'ultimo elemento di l'array).

Per manipolare array come questo è necessario splice, che rimuove correttamente gli elementi e sposta quelli successivi verso il basso per riempire lo spazio. Utilizzare

splice @{ $XML->{object} }, $n, 1 

al posto del tuo delete e il codice dovrebbe funzionare per voi.

2

Non utilizzare mai exists e delete su un elemento di matrice. Né fare nulla di utile.

Per rimuovere un elemento da un array, è necessario spostare verso il basso tutti gli altri elementi. splice può farlo.

splice(@{ $XML->{object} }, $n, 1); 

O se ti aiuta a capire meglio,

splice(@{ $XML->{object} }, $n, 1,()); 
+0

Fantastico - funziona! Penso di aver avuto una cattiva idea di cosa fossero esattamente gli array Perl, ma questo chiarisce perfettamente. Grazie mille! – marmarta

Problemi correlati