snehit.ar has asked for the wisdom of the Perl Monks concerning the following question:

Hi , I am trying to convert below data to json : Once its store in json ,will send data to httprequest using LWP::UserAgent. Also getting this string "'remedy_queue' => bless( [], 'XML::XPath::NodeSet' )," in my records.How to remove this?
$VAR1 = { 'appname' => 'IPT(957)', 'event_time' => '2017-06-06 15:37:17', 'line' => 1, 'ticketnum' => 'INC000015345', 'remedy_queue' => 'Coll@borate-L3', 'severity' => 'critical' }; $VAR2 = { 'appname' => 'Instant Messaging - Lync External(2667)', 'remedy_queue' => bless( [], 'XML::XPath::NodeSet' ), 'event_time' => '2017-04-07 13:54:51', 'line' => 2, 'ticketnum' => 'INC0000134513', 'severity' => 'critical' }; $VAR3 = { 'severity' => 'critical', 'event_time' => '2017-04-07 13:54:50', 'line' => 3, 'ticketnum' => 'INC00001847651', 'remedy_queue' => 'Global Service Desk', 'appname' => 'Instant Messaging - Lync External(2667)' };
Perl Code: Please do optimized below CODE if required ..
##!/usr/bin/perl use warnings; use strict; use XML::XPath; use Data::Dumper; use LWP::UserAgent; use JSON; use DateTime; use DateTime::Duration; use DateTime::Format::Duration; use DateTime::Format::Strptime; use Cpanel::JSON::XS qw(encode_json); my $xml = 'events.xml'; my $xp = XML::XPath->new(filename => $xml); my $nodeset = $xp->findnodes('//event'); my $records = []; my $count=0; foreach my $node ($nodeset->get_nodelist) { $count ++; my $severity = $xp->find('./severity', $node); $severity =~ s/\n//; my $ticketnum = $xp->find("./custom_attribute_list/custom_att +ribute[normalize-space(name)='RemedyIncident']/value", $node); $ticketnum=~ s/\n//; my $timereceived = $xp->find('./time_first_received', $node); $timereceived=~ s/\n//; my $service_name = $xp->find("./custom_attribute_list/custom_a +ttribute[normalize-space(name)='Service Name']/value", $node); $service_name=~ s/\n//; my $ssrid = $xp->find("./custom_attribute_list/custom_attribut +e[normalize-space(name)='SSRID']/value", $node); $ssrid=~ s/\n//; my $remedyqueue = $xp->find("./custom_attribute_list/custom_at +tribute[normalize-space(name)='RemedyQueue']/value", $node); $remedyqueue=~ s/\n//; #Format $timereceived $timereceived =~ s/T/ /; #removing the T $timereceived =~ s/\.\d+Z//; #removing the Z my $dtnow = DateTime->now; my $strp = DateTime::Format::Strptime->new(on_error=>'croak',p +attern => '%Y-%m-%d %H:%M:%S', time_zone=>'UTC'); my $dtevent = $strp->parse_datetime($timereceived); my $diff_sec = $dtnow->subtract_datetime_absolute($dtevent)->i +n_units('seconds'); my $diff_hours = $diff_sec/(60*60); #print "$diff_sec s / $diff_hours h\n"; #if ($diff_hours>4000) { ##//TODO:delete after testing the out +put if ($diff_hours>2) { push @$records, { line => $count, severity => $severity, ticketnum => $ticketnum, appname => $service_name . "(" . $ssrid . ")", remedy_queue => $remedyqueue, event_time => $timereceived, } } } print Dumper(@$records); # my $uri = 'http://testing/dims/line/tags/availability'; # my $json = '{ # "line":"4", # "status":"Critical", # "appname":"aaa", # "ticketnumber":"INC0012312312312", # "eventage":"0.5 h", # "specialist":"Guru" # }'; # my $req = HTTP::Request->new( 'POST', $uri ); # $req->header( 'Content-Type' => 'application/json'); # $req->content( $json ); # my $lwp = LWP::UserAgent->new; # $lwp->request( $req );

Replies are listed 'Best First'.
Re: array data to json
by choroba (Cardinal) on Jul 05, 2017 at 09:02 UTC
    The problem is that $remedyqueue doesn't contain an array (or better an array reference), but an XML::XPath::NodeSet object. You need to turn it to an array by using the get_nodelist method, but it returns a list of objects, so you need to convert them to something simpler - as you haven't shown the input XML, we can only guess, in my example, I used the string_value method:
    #!/usr/bin/perl use warnings; use strict; use XML::XPath; use JSON; my $dom = 'XML::XPath'->new(xml => '<r><a>1</a><a>2</a><a>3</a></r>'); my $remedy_queue = $dom->find('/r/a'); print encode_json([ map $_->string_value, $remedy_queue->get_nodelist +]), "\n";

    Output:

    ["1","2","3"]

    BTW, if the newline comes last in the values, you can replace $var =~ s/\n//; by more common

    chomp $var;

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      ++. And chomp even works on a list, so all variables can be handled in one call : chomp($severity, $ticketnum, $timereceived, $service_name, $ssrid, $remedyqueue);

        if i use chomp instead of $severity =~ s/\n//; its goes in infinite loop to retrieve the data ..
      Sorry ,but i dont able to solve any of the problem with the give suggestions. let me know if any other information required.
        Let me repeat

        > as you haven't shown the input XML, we can only guess

        So, to be explicit, the input XML is required.

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: array data to json
by ikegami (Patriarch) on Jul 07, 2017 at 18:47 UTC
    About the newlines and chomp, you should probably should be trimming.
    sub trim(_) { $_[0] =~ s/^\s+|\s++\z//rg } my $severity = trim $xp->find('./severity', $node); my $remedyqueue_xpath = "..."; my $remedyqueue = [ map trim, $xp->find($remedyqueue_xpath)->get_nodelist() ];