Reputation: 2983
I am currently trying to write a Perl function that can write XML to a file. The recommend module to use is XML::Simple
. I have written the code below, and I see XML output, but I don't see what I am trying to output. I have attached my code, the result, and my expected output. What am I doing wrong?
#!/usr/bin/perl
use strict;
use warnings;
use XML::Simple;
sub writexmlout {
my $hashref = {
'Contracts' => {
'ShortName' => '123231123'
},
'CallStates' => {
'CallStatesSPR' => {
'Name' => 'Acknowledged'
}
},
'ContractElements' => {
'ShortName' => 'test'
},
'Calls' => {
'CHD' => {
'FirstName' => 'Ron',
'LastName' => 'Rich',
'Tel' => '(123) 456-4567',
'Sign' => 'B2B',
'Email' => 'ron.rich@mavenir.com'
},
'SPCallID' => '12',
'Remarks' => 'Ticket successfully Ebonded',
'CustCallID' => '6199999'
}
};
# Create object
my $xml = new XML::Simple( NoAttr => 1,
SuppressEmpty => 1,
XMLDecl => 1 ,
RootName=>'CallData');
my $result = $xml->XMLout($hashref);
print $result;
}
writexmlout();
Unexpected results
<?xml version='1.0' standalone='yes'?>
<CallData>
<CallStates>
<name>CallStatesSPR</name>
<Name>Acknowledged</Name>
</CallStates>
<Calls>
<CHD>
<Email>ron.rich@mavenir.com</Email>
<FirstName>Ron</FirstName>
<LastName>Rich</LastName>
<Sign>B2B</Sign>
<Tel>(123) 456-4567</Tel>
</CHD>
<CustCallID>6199999</CustCallID>
<Remarks>Ticket successfully Ebonded</Remarks>
<SPCallID>12</SPCallID>
</Calls>
<ContractElements>
<ShortName>test</ShortName>
</ContractElements>
<Contracts>
<ShortName>123231123</ShortName>
</Contracts>
</CallData>
Desired results
<?xml version='1.0' standalone='yes'?>
<CallData>
<CallStates>
<CallStatesSPR>
<Name>Acknowledged</Name>
</CallStatesSPR>
</CallStates>
<Calls>
<CHD>
<Email>ron.rich@mavenir.com</Email>
<FirstName>Ron</FirstName>
<LastName>Rich</LastName>
<Sign>B2B</Sign>
<Tel>(123) 456-4567</Tel>
</CHD>
<CustCallID>6199999</CustCallID>
<Remarks>Ticket successfully Ebonded</Remarks>
<SPCallID>12</SPCallID>
</Calls>
<ContractElements>
<ShortName>test</ShortName>
</ContractElements>
<Contracts>
<ShortName>123231123</ShortName>
</Contracts>
</CallData>
Why is this occurring? How come the tag "name" appears which I am not expecting?
Upvotes: 1
Views: 747
Reputation: 126762
The correct way to do this is to disable attribute folding altogether. The previous answers work only because they have restricted array folding to attributes that exist nowhere in your source. Since your XML has no attributes at all you should set KeyAttr
to an empty list with
KeyAttr => {},
which correctly produces the output
<CallStates>
<CallStatesSPR>
<Name>Acknowledged</Name>
</CallStatesSPR>
</CallStates>
May I add that I believe XML::Simple
could be a bad choice, and this is unlikely to be that last of your problems. Consider XML::DOM
or XML::LibXML
if you begin to lose patience.
Upvotes: 4
Reputation: 22272
The KeyAttr =>
option will allow you to specify item names that you want as primary keys. In your case, for example, you want KeyAttr => { CallStatesSPR => 'name'}
Upvotes: 0
Reputation:
You need to use the KeyAttr
option:
my $result = $xml->XMLout($hashref,KeyAttr=>{item=>"CallStatesSPR"});
I'm not terribly experienced with XML::Simple
, but from what I can gather, this option tells the parser that you want to consider CallStatesSPR
to be an item and to put the resulting hash reference inside of <CallStatesSPR>
tags.
Upvotes: 0