2

I am using perl for converting an XML file JSON. I was able to write the code for converting the input XML file to Json format.

Here is the sample xml:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
   <Person SchemaVersion="1.0.8">
      <ID>0</ID>

      <Home ID="ABC-XYZ" State="Unknown">
         <Location>
            <SiteName></SiteName>
            <Number>62</Number>
            <MaxSize>0</MaxSize>
            <Comment></Comment>
         </Location>

         <Laptop>
             <FileName>/usr/temp/RPM_020515_.tar.gz</FileName>
         </Laptop>
    </Home>
  </Person>

sample perl code doing json conversion:

#!/usr/bin/perl

use JSON;
use XML::Simple;

# Create the object of XML Simple
my $xmlSimple = new XML::Simple(KeepRoot   => 1);

# Load the xml file in object
my $dataXML = $xmlSimple->XMLin("input/path/to/above/XMLFILE");

# use encode json function to convert xml object in json.
my $jsonString = encode_json($dataXML);

# finally print json
print $jsonString;

Output JSON value:

{
    "Person": {
       "ID": "0", 
       "SchemaVersion": "1.0.8", 
       "Home": {
          "ID": "ABC-XYZ", 

          "Laptop": {
             "FileName": "/usr/temp/RPM_020515_.tar.gz"
           }, 

          "Location": {
              "Number": "62", 
              "MaxSize": "0", 
              "Comment": { }, 
              "SiteName": { }
           }, 

          "State": "Unknown"
       }
   }
}

Above code is working fine.

My question is and this is where i am actually stuck.

I need to do one more thing along with JSON conversion which is checking if element "FileName" in XML is empty or not. if its not extract its value as well.

So output will be two things:
1. XML To JSON convert ( working fine )
2. Along with point 1. extract the value of nested element in XML        
   "FileName". I need that for some business logic need in next step.

Can some perl experts help me here and suggest me how i can do that in my current perl code.

Thanks for helping in advance. This is my first perl script so please excuse me if this is a too trivial question to ask.

Tried reading the perl docs but not that helpful.

NOTE: I am trying to use only perl built in libraries not any new third party libraries that is the reason i used XML::Simple. Its production code restriction ( very bad boundation ). I hope something for this exists in XML::Simple or JSON.

user1188611
  • 945
  • 2
  • 14
  • 38
  • You might like to read [this article](http://www.perlmonks.org/index.pl?node_id=218480) on using XML::Simple. One thing that worries me about your code is are there any XML elements that could repeat? For example, could a `` have more than one ``? – Grant McLean Feb 10 '15 at 23:06
  • 2
    Don't use XML::Simple. It isn't. It is for simple XML. Try something like XML::Twig instead. – Sobrique Feb 10 '15 at 23:09
  • 1
    Re. *"I am trying to use only perl built in libraries not any new third party libraries that is the reason i used XML::Simple."* `XML::Simple` is not a core module...what other non-core modules does your company deem acceptable? – ThisSuitIsBlackNot Feb 10 '15 at 23:09
  • @GrantMcLean: yes XML might have repeated elements, do you think code wont be able to handle this condition? – user1188611 Feb 11 '15 at 04:29
  • Yes, the fact that you have not used either the ForceArray or KeyAttr options recommended in the article I linked means that the shape of the data structure will change significantly when elements are repeated. [Read the article](http://www.perlmonks.org/index.pl?node_id=218480) :-) – Grant McLean Feb 11 '15 at 07:55

2 Answers2

1

As XML::Simple docs note, it 'slurps' the XML into a data structure analogous to the input XML. Thus, to figure out the contents of the XML, just treat it as the hash reference it likely is:

if ($dataXML->{Person}{Home}{ID} eq 'foo') {
   # Some action
   ...
}
Oesor
  • 6,632
  • 2
  • 29
  • 56
  • Yes this should work but only for those XML when path to element "FileName" is always same but if path changes then this wont produce the required value. Can you suggest something which is not hard coded? – user1188611 Feb 10 '15 at 22:54
  • You'd have to walk the data structure, but I'd suggest Data::Diver, or getting a XML library in place that supports xpath - http://stackoverflow.com/questions/3700069/how-can-i-check-if-a-key-exists-in-a-deep-perl-hash – Oesor Feb 10 '15 at 22:56
  • I am not able to reproduce the the way you mentioned can you give an example? – user1188611 Feb 11 '15 at 02:47
1

You should use XML::LibXML instead of XML::Simple. Then use xpath to query each document. I'd take a look at the code of XML::XML2JSON to see if it can be a good fit for the problem…

lnrdo
  • 396
  • 1
  • 13
  • so you mean to say that if i use XML::Simple i wont be able to get value of specific element "FileName" and i need to redesign my original perl code... Initially i started with XML:XML2JSON but was not able to generate the JSON in the format i have showed above... – user1188611 Feb 11 '15 at 02:46
  • So you are not only converting from XML to JSON, you are also translating from one data structure to another. I would guess you are having issues merging child elements with elements attributes. – lnrdo Feb 13 '15 at 20:24