我正在尝试使用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>
...
我需要回收所有东西,但尽管我付出了最大的努力,但到目前为止我还没有找到。
答案 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
选项导致属性转换为嵌套元素。
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' );