Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XML::Simple's "XMLout" method is converting attributes to elements

I am attempting to use XML::Simple to update a few Java applications' server.xml files. While I am able to parse and update the object fine, the output from XMLout is giving me some trouble. It seems to insist on expanding all the original attributes into single elements which confuses my Java application when it starts up.

Here is an example of part of the 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>  

Me making a small change via XMLin:

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

I then output my file like this:

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

Everything seems to work fine and look good in Data::Dumper but when I look at my output I now have XML like this:

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

I need everything to be rolled back up but despite my best efforts this has eluded me so far.

like image 990
insultant Avatar asked Aug 16 '26 22:08

insultant


2 Answers

It's hard enough to use XML::Simple for input, but output is very near impossible. I use 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');
like image 170
ikegami Avatar answered Aug 19 '26 16:08

ikegami


Reading the documentation of XML::Simple on CPAN, it seems like the NoAttr => 1 option in XMLout method is causing attributes to be converted to nested elements.

To quote the relevant part,

NoAttr => 1 # in+out - handy

When used with XMLout(), the generated XML will contain no attributes. All hash key/values will be represented as nested elements instead.

like image 26
doubleDown Avatar answered Aug 19 '26 17:08

doubleDown