2013-01-17 14 views
5

Jestem nowy w XML::Twig. Jak mogę zmienić wszystkie puste elementy, aby używać tagów pustego elementu (<foo/>) zamiast kombo start-tag i tagu końcowego (<foo></foo>)?Jak zmienić XML, aby używać tagów pustych elementów?

Wejście:

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

muszę wyjście jak:

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

Próbowałem:

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

Ale nie mogę przetworzyć. Jak zmienić gloabalnie bez tagu zawartości na pusty tag? jak mogę się zmienić?

+3

'

' i '

' są po prostu różnymi reprezentacjami tych samych danych. Dlaczego ma znaczenie to, którego używasz? – Quentin

+0

Usuwam niechciane zamykanie i zmniejszam rozmiar pliku tak wiele celów ... do tego przy użyciu ... – user1811486

Odpowiedz

2

Jeśli chcesz trzymać się gałązka, można to zrobić tak:

#!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; 

Zasadniczo trzeba ręcznie sprawdzić, czy element zawiera niczego, a następnie ustawić go do być pustym elementem.

5

XML :: LibXML automatycznie wypisze krótszą wersję.

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

jako XML :: Twig, ale także korzysta z krótszą formę Domyślnie (empty_tags => 'normal'). Jednak uwzględnia tylko puste elementy, które zostały utworzone z <foo/>. (Wydaje mi się to dość głupie!) Zrobiłem trochę kopania i stwierdziłem, że pozwala ci to zmienić, jeśli uzna, że ​​element jest pusty. Odbywa się to za pomocą set_empty i 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

Dodano XML :: Twig solution. – ikegami

+0

IIRC powodem, dla którego jedynymi elementami uznanymi za puste są te, które zostały utworzone z pustym znacznikiem, jest ułatwienie wypłukania elementu w dowolnym momencie (w tym zaraz po analizie znacznika początkowego). Ponieważ to, o co prosi OP, jest dość niecodzienne i niezbyt interesujące XML-owo, XML :: Twig nie obsługuje go "łatwo". Wydaje się, że dużo częściej użytkownicy chcą zachować wyjściowy kod XML jak najbliżej danych wejściowych, co domyślnie robi XML :: Twig. – mirod

+0

@mirod, Albo skończyłeś sprawdzać element, albo nie. To, w jaki sposób powstaje, gdy skończysz, nie ma znaczenia, kiedy można go przepłukać. – ikegami

Powiązane problemy