2013-01-17 11 views
5

Sono nuovo a XML::Twig. Come posso modificare tutti gli elementi vuoti per utilizzare i tag elemento vuoto (<foo/>) invece di un combo start-tag e end-tag (<foo></foo>)?Come modificare XML per utilizzare i tag elemento vuoto?

ingresso:

<book> 
    <given-names>Maurice<xref ref-type="fn" rid="fnI_1"></xref></given-names> 
    <colspec colname="col1" colnum="1"></colspec> 
    <entry align="left"><p></p></entry> 
</book> 

Ho bisogno di output come:

<book> 
    <given-names>Maurice<xref ref-type="fn" rid="fnI_1"/></given-names> 
    <colspec colname="col1" colnum="1"/> 
    <entry align="left"><p/></entry> 
</book> 

ho provato:

 use XML::Twig; 
     my $xml = XML::Twig->new(twig_handlers => { 
            'xref' => sub {$_->set_tag('#EMPTY'),}, 
           }, 
           pretty_print => 'indented',           
           ); 
     $xml->parse('sample.xml'); 
     $xml->print; 
} 

ma non riesco a elaborarlo. Come può cambiare a livello globale senza tag di contenuto per tag vuoto? come posso cambiare?

+3

'

' e '

' sono solo rappresentazioni differenti degli stessi dati. Perché è importante quale si usa? – Quentin

+0

Rimuovere la chiusura indesiderata e ridurre le dimensioni del file per molti scopi .. per questo utilizzo ... – user1811486

risposta

2

Se si vuole attaccare con Twig, si può fare in questo modo:

#!usr/bin/perl 
use strict; 
use warnings; 
use XML::Twig; 

my $xml = XML::Twig->new(twig_handlers => { 
      'p' => sub { 
       if (!$_->first_child()) { $_->set_content('#EMPTY') } 
       }, 
      }, 
      pretty_print => 'indented', 
      empty_tags => 'normal'         
); 

$xml->parsefile('file.xml'); 
$xml->print; 

In pratica dovete controllare manualmente se l'elemento non contiene nulla, quindi impostarlo per essere un elemento vuoto.

5

XML :: LibXML emetterà automaticamente la versione più corta.

use XML::LibXML qw(); 
print XML::LibXML->new()->parse_file($ARGV[0])->toString(); 

Per quanto riguarda XML :: Twig, utilizza anche la forma più breve di default (empty_tags => 'normal'). Tuttavia, considera solo gli elementi vuoti quelli che sono stati creati da <foo/>. (Mi sembra abbastanza stupido!) Ho fatto qualche ricerca e ho scoperto che ti permette di cambiare se considera un elemento vuoto o meno. Questo viene fatto usando set_empty e set_not_empty.

use XML::Twig qw(); 
my $twig = XML::Twig->new(
    twig_handlers => { 
     '*' => sub { 
     $_->set_empty() if !$_->first_child(); 
     }, 
    }, 
); 
$twig->parsefile($ARGV[0]); 
$twig->print(); 
+0

Soluzione XML :: Twig aggiunta. – ikegami

+0

IIRC il motivo per cui gli unici elementi considerati vuoti sono quelli creati con un tag vuoto per semplificare lo svuotamento dell'elemento in qualsiasi momento (anche subito dopo l'analisi del tag di inizio). Poiché ciò che l'OP richiede è abbastanza raro, e non di grande interesse per XML, XML :: Twig non lo supporta "facilmente". Sembra molto più comune per gli utenti di voler mantenere l'XML di output il più vicino possibile all'input, che è ciò che XML :: Twig fa per impostazione predefinita. – mirod

+0

@mirod, O hai finito di ispezionare l'elemento o meno. Il modo in cui viene emesso quando hai finito non fa alcuna differenza quando può essere svuotato. – ikegami

Problemi correlati