pitchblack408
pitchblack408

Reputation: 2983

Why is the XML::simple module in Perl not outputting the expected format?

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

Answers (3)

Borodin
Borodin

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

Wes Hardaker
Wes Hardaker

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

user554546
user554546

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

Related Questions