XML :: Simple的“XMLout”方法是将属性转换为元素

时间:2013-06-21 23:14:19

标签: xml perl server.xml

我正在尝试使用XML :: Simple来更新一些Java应用程序的server.xml文件。虽然我能够很好地解析和更新对象,但XMLout的输出给了我一些麻烦。它似乎坚持将所有原始属性扩展为单个元素,这些元素在启动时会混淆我的Java应用程序。

以下是XML的一部分示例:

<Server port="9000" shutdown="SHUTDOWN">
<Service name="Catalina">
<Connector port="9002" redirectPort="8443" enableLookups="false" protocol="AJP/1.3"     URIEncoding="UTF-8"/>
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on"/>
</Service>
</Server>  

我通过XMLin进行了一些小改动:

$xml->XMLin("server.xml", ForceArray => ['Connector']);
$server_xml->{'port'} = $server_port;
$server_xml->{'Service'}->{'Connector'}->[0]->{'port'} = $http_port;

然后我输出我的文件:

XMLout($server_xml, RootName => 'Server',  KeepRoot => 0, NoAttr => 1, OutputFile => "server.xml");

在Data :: Dumper中,一切似乎工作正常并且看起来很好但是当我查看我的输出时,我现在有这样的XML:

   <Server>
   <Listener>
   <SSLEngine>on</SSLEngine>
   <className>org.apache.catalina.core.AprLifecycleListener</className>
   </Listener>
   ...

我需要回收所有东西,但尽管我付出了最大的努力,但到目前为止我还没有找到。

3 个答案:

答案 0 :(得分:10)

使用XML :: Simple进行输入很难,但输出几乎是不可能的。我使用XML::LibXML

use XML::LibXML qw( );

my $parser = XML::LibXML->new();
my $doc = $parser->parse_file('server.xml');

for my $server ($doc->findnodes('/Server')) {
   $server->setAttribute(port => $server_port);

   for my $connector ($server->findnodes('Service/Connector[0]') {
      $connector->setAttribute(port => $http_port);
   }
}

$doc->toFile('server.xml');

答案 1 :(得分:3)

在CPAN上阅读XML :: Simple的文档,似乎NoAttr => 1方法中的XMLout选项导致属性转换为嵌套元素。

引用relevant part

  

NoAttr =&gt; 1#in + out - 得心应手

     

与XMLout()一起使用时,生成的XML将不包含任何属性。所有散列键/值都将表示为嵌套元素。

答案 2 :(得分:2)

我建议你像这样使用XML::Twig

use XML::Twig;

my $change_port = sub { $_->set_att( port => 1234 ) };

my $twig = XML::Twig->new(
    twig_handlers => {
        'Server[@port]' => $change_port,
        'Connector[@port]' => $change_port,
    },
);
$twig->parsefile( 'server.xml' );
$twig->print_to_file( 'server.xml' );