5

我是XML::Twig的新手。如何更改所有空元素以使用空元素标签 ( <foo/>) 而不是开始标签和结束标签组合 ( <foo></foo>)?

输入:

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

我需要输出为:

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

我试过:

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

但我无法处理它。如何在没有内容标签的情况下全局更改为空标签?我该如何改变?

4

2 回答 2

5

XML::LibXML 将自动输出较短的版本。

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

至于 XML::Twig,它也默认使用较短的形式 ( empty_tags => 'normal')。但是,它只考虑那些从创建的空元素<foo/>。(对我来说似乎很愚蠢!)我做了一些挖掘,发现它确实允许你改变它是否认为一个元素是空的。这是使用set_empty和完成的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();
于 2013-01-17T09:41:25.643 回答
2

如果你想坚持使用 Twig,你可以这样做:

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

基本上你必须手动检查元素是否包含任何内容,然后将其设置为空元素。

于 2013-01-17T09:55:42.750 回答