2

我正在尝试使用 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>
   ...

我需要把所有东西都卷起来,但尽管我尽了最大的努力,但到目前为止我还没有做到这一点。

4

3 回答 3

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');
于 2013-06-21T23:27:10.213 回答
3

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

引用相关部分

NoAttr => 1 # in+out - 方便

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

于 2013-06-22T06:00:09.750 回答
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' );
于 2013-06-22T11:03:13.920 回答