taralon has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

Let me preface my issue with some introductory information. I have recently taken over the creation and management of tools written in Perl at my job. Until six months ago my Perl coding was minimal, the learning curve has been a bit steep, but I have found a way around all my issues to date by reading posts on this, and other sites. Most of my coding background comes from college classes that are now, unfortunately, 16+ years in the past.

I have now run into an issue that I just can't seem to wrap my head around.

We have log files at work that contain returns from outside machines in XML format. I could parse the returns using combinations of split and regular expressions to get what I need out of the XML but I have been trying to parse the XML with XML::Simple (tried using XML::LibXML as well but I can't get it to return a valid data structure so I have put that on a back burner again). However, when I try to step through the data structure returned by XML::Simple, I get nowhere. I am obviously missing something, but I haven't been able to find out what by reading posts and such online. I hope that someone will point out where and why I am going wrong.

Below is a test version of the code I am using for the XML Portion of the code. Everything up to this point works as I expect it to, so I will just post that. Typically I would be running a "foreach my $xmlfile (@logfileperformancelist)" to lead into this code. Forgive me as the code blocks are going to be long as I have included some test data directly in the code as I was checking to see how this works, and the data structure given by Data::Dumper below that as well.

use strict; use warnings; use XML::Simple; use Data::Dumper; use File::Slurp; ## test script to verify the way xml is parsed## ## $xmlfile is set to data of a format that would be expected to b +e passed to this if used in a loop ## my $xmlfile = '<?xml version="1.0" encoding="UTF-8"?><TMSMessage x +mlns="http://xmlns.sony.net/d-cinema/tms-api/v1"><MessageHeader><Id>- +1</Id><Type>ListPerformances</Type><Timestamp>1433796462559</Timestam +p><Source>TMS</Source></MessageHeader><MessageBody><ListPerformancesR +esponse><EventInfoList><EventInfo><EventId>2015060400000157</EventId> +<EventTitle>zClosing Shutdown 3D v6 - New</EventTitle><SplId>20100101 +00000038</SplId><SplTitle>zClosing Shutdown 3D v6 - New</SplTitle><Au +ditoriumId>15</AuditoriumId><AuditoriumNo>15</AuditoriumNo><EventStar +tTime>2015-06-08T00:30:00-07:00</EventStartTime><DcpFlg>true</DcpFlg> +<KdmFlg>true</KdmFlg><EventDuration>464</EventDuration><ShowStartTime +>2015-06-08T00:30:00-07:00</ShowStartTime><ShowDuration>464</ShowDura +tion><SpokenLang></SpokenLang><SubtitleLang></SubtitleLang><Rating></ +Rating><OverlappedEventFlg>false</OverlappedEventFlg><UncompletedShow +Flg>false</UncompletedShowFlg><HavingShowFlg>true</HavingShowFlg><Eve +ntBodyColor>696969</EventBodyColor><ImportFlg>false</ImportFlg><Overl +appedNum>1</OverlappedNum><HeightPos>0</HeightPos><WaitGPIFlg>false</ +WaitGPIFlg><EventEndTime>2015-06-08T00:37:44-07:00</EventEndTime><Thr +eeDimension>true</ThreeDimension><EventStatus>0</EventStatus><Importe +dShowId></ImportedShowId><ImportedAnalogFlg>false</ImportedAnalogFlg> +<EventRating></EventRating><RatingFlg>true</RatingFlg><PreshowPackLis +t></PreshowPackList></EventInfo><EventInfo><EventId>2015060400000164< +/EventId><EventTitle>zMorning Startup 3D v3</EventTitle><SplId>201106 +1100000013</SplId><SplTitle>zMorning Startup 3D v3</SplTitle><Auditor +iumId>15</AuditoriumId><AuditoriumNo>15</AuditoriumNo><EventStartTime +>2015-06-08T12:10:00-07:00</EventStartTime><DcpFlg>true</DcpFlg><KdmF +lg>true</KdmFlg><EventDuration>10</EventDuration><ShowStartTime>2015- +06-08T12:10:00-07:00</ShowStartTime><ShowDuration>10</ShowDuration><S +pokenLang></SpokenLang><SubtitleLang></SubtitleLang><Rating></Rating> +<OverlappedEventFlg>false</OverlappedEventFlg><UncompletedShowFlg>fal +se</UncompletedShowFlg><HavingShowFlg>true</HavingShowFlg><EventBodyC +olor>696969</EventBodyColor><ImportFlg>false</ImportFlg><OverlappedNu +m>1</OverlappedNum><HeightPos>0</HeightPos><WaitGPIFlg>false</WaitGPI +Flg><EventEndTime>2015-06-08T12:10:10-07:00</EventEndTime><ThreeDimen +sion>true</ThreeDimension><EventStatus>0</EventStatus><ImportedShowId +></ImportedShowId><ImportedAnalogFlg>false</ImportedAnalogFlg><EventR +ating></EventRating><RatingFlg>true</RatingFlg><PreshowPackList></Pre +showPackList></EventInfo><EventInfo><EventId>2015060200000562</EventI +d><EventTitle>* Movie1 3D-AV</EventTitle><SplId>2015060800000048</Spl +Id><SplTitle>w23_3DP1_Sanandreas_SCCAP_0421pre_150605_02222_TMS_</Spl +Title><AuditoriumId>15</AuditoriumId><AuditoriumNo>15</AuditoriumNo>< +EventStartTime>2015-06-08T12:55:00-07:00</EventStartTime><DcpFlg>true +</DcpFlg><KdmFlg>true</KdmFlg><EventDuration>8195</EventDuration><Sho +wStartTime>2015-06-08T12:29:18-07:00</ShowStartTime><ShowDuration>973 +7</ShowDuration><SpokenLang>en,en,en,en,en,en,en,en,en,en</SpokenLang +><SubtitleLang></SubtitleLang><Rating>US-G US-G US-G US-G + US-G US-G US-G US-G US-G US-G + </Rating><OverlappedEventFlg>false</OverlappedEventFlg><Uncomple +tedShowFlg>false</UncompletedShowFlg><HavingShowFlg>true</HavingShowF +lg><EventBodyColor>696969</EventBodyColor><ImportFlg>true</ImportFlg> +<OverlappedNum>1</OverlappedNum><HeightPos>0</HeightPos><WaitGPIFlg>f +alse</WaitGPIFlg><EventEndTime>2015-06-08T15:11:35-07:00</EventEndTim +e><ThreeDimension>true</ThreeDimension><EventStatus>0</EventStatus><I +mportedShowId>00343929</ImportedShowId><ImportedAnalogFlg>false</Impo +rtedAnalogFlg><EventRating>US-13</EventRating><RatingFlg>true</Rating +Flg><PreshowPackList><PreshowPack><PackId>b863a576-d8a3-4f5d-92a7-b66 +f876f6d7c</PackId><FrameName>Preshow</FrameName><FrameNumber>1</Frame +Number></PreshowPack><PreshowPack><NoAssign>true</NoAssign><FrameName +>3D_Advertisement</FrameName><FrameNumber>1</FrameNumber></PreshowPac +k><PreshowPack><PackId>a55164d0-faa7-4c7c-a688-ed36011add95</PackId>< +FrameName>Postshow</FrameName><FrameNumber>1</FrameNumber></PreshowPa +ck></PreshowPackList></EventInfo><EventInfo><EventId>2015060200000563 +</EventId><EventTitle>* Movie1 3D-AV</EventTitle><SplId>2015060600000 +017</SplId><SplTitle>w23_3DP1_Sanandreas_SCCAP_0421pre_150605_02062_T +MS_</SplTitle><AuditoriumId>15</AuditoriumId><AuditoriumNo>15</Audito +riumNo><EventStartTime>2015-06-08T16:05:00-07:00</EventStartTime><Dcp +Flg>true</DcpFlg><KdmFlg>true</KdmFlg><EventDuration>8195</EventDurat +ion><ShowStartTime>2015-06-08T15:42:13-07:00</ShowStartTime><ShowDura +tion>9562</ShowDuration><SpokenLang>en,en,en,en,en,en,en,en,en,en</Sp +okenLang><SubtitleLang></SubtitleLang><Rating>US-G US-G US-G + US-G US-G US-G US-G US-G US-G US-G + </Rating><OverlappedEventFlg>false</OverlappedEventFlg><Unc +ompletedShowFlg>false</UncompletedShowFlg><HavingShowFlg>true</Having +ShowFlg><EventBodyColor>FFFFFF</EventBodyColor><ImportFlg>true</Impor +tFlg><OverlappedNum>1</OverlappedNum><HeightPos>0</HeightPos><WaitGPI +Flg>false</WaitGPIFlg><EventEndTime>2015-06-08T18:21:35-07:00</EventE +ndTime><ThreeDimension>true</ThreeDimension><EventStatus>0</EventStat +us><ImportedShowId>00343929</ImportedShowId><ImportedAnalogFlg>false< +/ImportedAnalogFlg><EventRating>US-13</EventRating><RatingFlg>true</R +atingFlg><PreshowPackList><PreshowPack><PackId>760eb073-81f8-45cb-855 +3-484c5cecb740</PackId><FrameName>Preshow</FrameName><FrameNumber>1</ +FrameNumber></PreshowPack><PreshowPack><NoAssign>true</NoAssign><Fram +eName>3D_Advertisement</FrameName><FrameNumber>1</FrameNumber></Presh +owPack><PreshowPack><PackId>a55164d0-faa7-4c7c-a688-ed36011add95</Pac +kId><FrameName>Postshow</FrameName><FrameNumber>1</FrameNumber></Pres +howPack></PreshowPackList></EventInfo></EventInfoList></ListPerforman +cesResponse></MessageBody></TMSMessage>'; my $performancelist=XMLin($xmlfile, forcearray => 1, KeyAttr => {EventInfo => 'EventId'} ## +#ventID is a unique value that I want to use as a key value ## ); write_file 'mydump.log', Dumper($performancelist); ## this is where nothing happens ## foreach my $performance (@{$performancelist->{MessageBody}->{ListP +erformancesResponse}->{EventInfoList}->{EventInfo}->{EventId}}) { my $output=$performance->{PreshowPackList}->{PreshowPack}->{Pa +ckId}; print "Debug: $output.\n"; }

Which errors out with:

"Not a HASH reference at xmlparse.pl line 15"

Looking at the output of Dumper I found that my keyattr isn't being keyed on at all. If I remove the forcearray=>1 from the above code, then Dumper does output what I expect, but it doesn't get me any closer to running correctly.

I believe that the problem I am running into is the fact that I only get one $var returned and I am trying to step through this as if an array. I thought that I could treat the key attribute that I referenced in the code as an array and step through that by referencing to it.

The output of Dumper is below:

$VAR1 = { 'xmlns' => 'http://xmlns.sony.net/d-cinema/tms-api/v1', 'MessageBody' => [ { 'ListPerformancesResponse' => [ { 'EventInf +oList' => [ + { + 'EventInfo' => [ + { + 'EventEndTime' => [ + '2015-06-08T00:37:44-0 +7:00' + ], + 'DcpFlg' => [ + 'true' + ], + 'EventRating' => [ + {} + ], + 'OverlappedEventFlg' => [ + 'false' + ], + 'ImportedShowId' => [ + {} + ], + 'ThreeDimension' => [ + 'true' + ], + 'EventDuration' => [ + '464' + ], + 'RatingFlg' => [ + 'true' + ], + 'ImportedAnalogFlg' => [ + 'false' + ], + 'AuditoriumNo' => [ + '15' + ], + 'SpokenLang' => [ + {} + ], + 'SplId' => [ + '2010010100000038' + ], + 'HavingShowFlg' => [ + 'true' + ], + 'UncompletedShowFlg' => [ + 'false' + ], + 'ShowStartTime' => [ + '2015-06-08T00:30:00- +07:00' + ], + 'ShowDuration' => [ + '464' + ], + 'EventBodyColor' => [ + '696969' + ], + 'EventStartTime' => [ + '2015-06-08T00:30:00 +-07:00' + ], + 'ImportFlg' => [ + 'false' + ], + 'EventTitle' => [ + 'zClosing Shutdown 3D v6 + - New' + ], + 'Rating' => [ + {} + ], + 'AuditoriumId' => [ + '15' + ], + 'WaitGPIFlg' => [ + 'false' + ], + 'HeightPos' => [ + '0' + ], + 'PreshowPackList' => [ + {} + ], + 'EventId' => [ + '2015060400000157' + ], + 'EventStatus' => [ + '0' + ], + 'SplTitle' => [ + 'zClosing Shutdown 3D v6 - + New' + ], + 'OverlappedNum' => [ + '1' + ], + 'SubtitleLang' => [ + {} + ], + 'KdmFlg' => [ + 'true' + ] + }, + { + 'EventEndTime' => [ + '2015-06-08T12:10:10-0 +7:00' + ], + 'DcpFlg' => [ + 'true' + ], + 'EventRating' => [ + {} + ], + 'OverlappedEventFlg' => [ + 'false' + ], + 'ImportedShowId' => [ + {} + ], + 'ThreeDimension' => [ + 'true' + ], + 'EventDuration' => [ + '10' + ], + 'RatingFlg' => [ + 'true' + ], + 'ImportedAnalogFlg' => [ + 'false' + ], + 'AuditoriumNo' => [ + '15' + ], + 'SpokenLang' => [ + {} + ], + 'SplId' => [ + '2011061100000013' + ], + 'HavingShowFlg' => [ + 'true' + ], + 'UncompletedShowFlg' => [ + 'false' + ], + 'ShowStartTime' => [ + '2015-06-08T12:10:00- +07:00' + ], + 'ShowDuration' => [ + '10' + ], + 'EventBodyColor' => [ + '696969' + ], + 'EventStartTime' => [ + '2015-06-08T12:10:00 +-07:00' + ], + 'ImportFlg' => [ + 'false' + ], + 'EventTitle' => [ + 'zMorning Startup 3D v3' + ], + 'Rating' => [ + {} + ], + 'AuditoriumId' => [ + '15' + ], + 'WaitGPIFlg' => [ + 'false' + ], + 'HeightPos' => [ + '0' + ], + 'PreshowPackList' => [ + {} + ], + 'EventId' => [ + '2015060400000164' + ], + 'EventStatus' => [ + '0' + ], + 'SplTitle' => [ + 'zMorning Startup 3D v3' + ], + 'OverlappedNum' => [ + '1' + ], + 'SubtitleLang' => [ + {} + ], + 'KdmFlg' => [ + 'true' + ] + }, + { + 'EventEndTime' => [ + '2015-06-08T15:11:35-0 +7:00' + ], + 'DcpFlg' => [ + 'true' + ], + 'EventRating' => [ + 'US-13' + ], + 'OverlappedEventFlg' => [ + 'false' + ], + 'ImportedShowId' => [ + '00343929' + ], + 'ThreeDimension' => [ + 'true' + ], + 'EventDuration' => [ + '8195' + ], + 'RatingFlg' => [ + 'true' + ], + 'ImportedAnalogFlg' => [ + 'false' + ], + 'AuditoriumNo' => [ + '15' + ], + 'SpokenLang' => [ + 'en,en,en,en,en,en,en,en +,en,en' + ], + 'SplId' => [ + '2015060800000048' + ], + 'HavingShowFlg' => [ + 'true' + ], + 'UncompletedShowFlg' => [ + 'false' + ], + 'ShowStartTime' => [ + '2015-06-08T12:29:18- +07:00' + ], + 'ShowDuration' => [ + '9737' + ], + 'EventBodyColor' => [ + '696969' + ], + 'EventStartTime' => [ + '2015-06-08T12:55:00 +-07:00' + ], + 'ImportFlg' => [ + 'true' + ], + 'EventTitle' => [ + '* Movie1 3D-AV' + ], + 'Rating' => [ + 'US-G US-G US-G U +S-G US-G US-G US-G US-G US-G US-G + ' + ], + 'AuditoriumId' => [ + '15' + ], + 'WaitGPIFlg' => [ + 'false' + ], + 'HeightPos' => [ + '0' + ], + 'PreshowPackList' => [ + { + 'PreshowPack' => +[ + +{ + + 'FrameName' => [ + + 'Preshow' + + ], + + 'FrameNumber' => [ + + '1' + + ], + + 'PackId' => [ + + 'b863a576-d8a3-4f5d-92a7-b66f876f6d7c' + + ] + +}, + +{ + + 'NoAssign' => [ + + 'true' + + ], + + 'FrameName' => [ + + '3D_Advertisement' + + ], + + 'FrameNumber' => [ + + '1' + + ] + +}, + +{ + + 'FrameName' => [ + + 'Postshow' + + ], + + 'FrameNumber' => [ + + '1' + + ], + + 'PackId' => [ + + 'a55164d0-faa7-4c7c-a688-ed36011add95' + + ] + +} + ] + } + ], + 'EventId' => [ + '2015060200000562' + ], + 'EventStatus' => [ + '0' + ], + 'SplTitle' => [ + 'w23_3DP1_Sanandreas_SCCAP +_0421pre_150605_02222_TMS_' + ], + 'OverlappedNum' => [ + '1' + ], + 'SubtitleLang' => [ + {} + ], + 'KdmFlg' => [ + 'true' + ] + }, + { + 'EventEndTime' => [ + '2015-06-08T18:21:35-0 +7:00' + ], + 'DcpFlg' => [ + 'true' + ], + 'EventRating' => [ + 'US-13' + ], + 'OverlappedEventFlg' => [ + 'false' + ], + 'ImportedShowId' => [ + '00343929' + ], + 'ThreeDimension' => [ + 'true' + ], + 'EventDuration' => [ + '8195' + ], + 'RatingFlg' => [ + 'true' + ], + 'ImportedAnalogFlg' => [ + 'false' + ], + 'AuditoriumNo' => [ + '15' + ], + 'SpokenLang' => [ + 'en,en,en,en,en,en,en,en +,en,en' + ], + 'SplId' => [ + '2015060600000017' + ], + 'HavingShowFlg' => [ + 'true' + ], + 'UncompletedShowFlg' => [ + 'false' + ], + 'ShowStartTime' => [ + '2015-06-08T15:42:13- +07:00' + ], + 'ShowDuration' => [ + '9562' + ], + 'EventBodyColor' => [ + 'FFFFFF' + ], + 'EventStartTime' => [ + '2015-06-08T16:05:00 +-07:00' + ], + 'ImportFlg' => [ + 'true' + ], + 'EventTitle' => [ + '* Movie1 3D-AV' + ], + 'Rating' => [ + 'US-G US-G US-G US +-G US-G US-G US-G US-G US-G US-G + ' + ], + 'AuditoriumId' => [ + '15' + ], + 'WaitGPIFlg' => [ + 'false' + ], + 'HeightPos' => [ + '0' + ], + 'PreshowPackList' => [ + { + 'PreshowPack' => +[ + +{ + + 'FrameName' => [ + + 'Preshow' + + ], + + 'FrameNumber' => [ + + '1' + + ], + + 'PackId' => [ + + '760eb073-81f8-45cb-8553-484c5cecb740' + + ] + +}, + +{ + + 'NoAssign' => [ + + 'true' + + ], + + 'FrameName' => [ + + '3D_Advertisement' + + ], + + 'FrameNumber' => [ + + '1' + + ] + +}, + +{ + + 'FrameName' => [ + + 'Postshow' + + ], + + 'FrameNumber' => [ + + '1' + + ], + + 'PackId' => [ + + 'a55164d0-faa7-4c7c-a688-ed36011add95' + + ] + +} + ] + } + ], + 'EventId' => [ + '2015060200000563' + ],

Update: <

Replies are listed 'Best First'.
Re: XML Parsing Problems
by tangent (Parson) on Jun 08, 2015 at 23:43 UTC
    tried using XML::LibXML as well but I can't get it to return a valid data structure
    You can use XML::LibXML but because of the xmlns="http://xmlns.sony.net..." in the TMSMessage tag you have to perform some namespace trickery. By referring to this node I came up with this snippet which may be of help:
    my $text = q|<?xml version="1.0" encoding="UTF-8"?> <TMSMessage xmlns="http://xmlns.sony.net/d-cinema/tms-api/v1"> <MessageHeader> <Id>-1</Id> <Type>ListPerformances</Type> ...etc </TMSMessage>|; my $doc = XML::LibXML->load_xml(string => $text); my $xc = XML::LibXML::XPathContext->new( $doc->documentElement() ); $xc->registerNs( pfx => 'http://xmlns.sony.net/d-cinema/tms-api/v1' ); my @events = $xc->findnodes('//pfx:EventInfo'); for my $event (@events) { my $id = $xc->findvalue('pfx:EventId', $event); print "EventId: $id\n"; my @packs = $xc->findnodes('pfx:PreshowPackList/pfx:PreshowPack', +$event); if ( not @packs ) { print "No Packs\n"; next; } for my $pack (@packs) { my $pack_id = $xc->findvalue('pfx:PackId', $pack) || "No PackI +d"; print "PackId: $pack_id\n"; } }
    Output using your sample XML:
    EventId: 2015060400000157 No Packs EventId: 2015060400000164 No Packs EventId: 2015060200000562 PackId: b863a576-d8a3-4f5d-92a7-b66f876f6d7c PackId: No PackId PackId: a55164d0-faa7-4c7c-a688-ed36011add95 EventId: 2015060200000563 PackId: 760eb073-81f8-45cb-8553-484c5cecb740 PackId: No PackId PackId: a55164d0-faa7-4c7c-a688-ed36011add95

      Thank you for posting that. I believe I am getting my head wrapped around it. Basically it seems that the XML that I am feeding into XML::LibXML->load_xml has a namespace in it and I need to declare what the namespace is, otherwise the comparison is vs the null namespace, which is why I wasn't getting a return I expected. If there was no namespace I don't need to declare it as comparing vs the null namespace would return correctly.

      Your code does do what I want it to do, but I think for the sake of future usability I will want to pull the value that I am going to be using for the pfx for name space out of the XML itself, push it into a variable, and use that variable to declare the namespace.

      During testing I have found that having whitespace before/after the "s in the namespace declaration causes issues. IE <TMSMessage xmlns=" http://xmlns.sony.net/d-cinema/tms-api/v1"> or <TMSMessage xmlns="http://xmlns.sony.net/d-cinema/tms-api/v1 ">. However this should be caught by the server sending the XML to us and I have not found any test data of this type, so currently I will not error handle for it. A few test samples of data show that our logs sometimes have a blank namespace declaration IE: <TMSMessage xmlns=""> (this throws a xpath error if I try to process it so I error out on finding this) or no namespace declaration IE: <TMSMessage> (this would not process with the code you provided as there is no namespace, I have added a if loop to process this instead). I have edited the code to catch this and either process or error out.

      Updated code is below. It likely could still use some polishing, but it catches all the test conditions I currently want.

      use strict; use warnings; use XML::LibXML; ## test script to verify the way xml is parsed## ## $xmlfile is set to data of a format that would be expected to b +e passed to this if used in a loop ## my $namespace; my $goodnamespace=1; my $namespacedeclared=0; my $xmlfile = '<?xml version="1.0" encoding="UTF-8"?><TMSMessage x +mlns="http://xmlns.sony.net/d-cinema/tms-api/v1"><MessageHeader><Id>- +1</Id><Type>ListPerformances</Type> ...etc </TMSMessage>'; if ($xmlfile =~ m/xmlns\=/) { + ## if a namespace is declared we want to extract i +t ## $namespacedeclared=1; + ## since we have a namespace, set the namespacedelcare + to 1 ## print "There is a namespace declared in the xmlfile. Extracti +ng it.\n"; my @namespacesplit=split(/xmlns\=\"/,$xmlfile); + ## split the xmlfile on the xmlns declaration. incl +ude the " so that we can discard this. ## my $tempnamespace=$namespacesplit[1]; + ## $namespacesplit[0] will contain everything before t +he declaration. [1] will contain the namespace at the beginning. I +like declare a new temp variable to use before feeding into the next +split.## my @finalnamespacesplit=split(/">/,$tempnamespace); + ## split our return again so that everything after t +he namespace gets split from the namespace ## $namespace=$finalnamespacesplit[0]; + ## finalnamespacesplit[0] should have the name space +. I have found that if the namespace is a "space" or a "tab" if it i +s declared but is nothing then the namespace won't work in processing + the xml as it is invalid. Will test for this ## my $lengthtest=$namespace; $lengthtest =~ s/\s+//g; + ## remove all spaces ## my $testlength = length ($lengthtest); + ## check the length of the namespace once all spaces +removed ## if ($testlength) { + ## If the length of the string after removing spaces +is greater than one, then we likely have a good namespace catches err +or if the namespace is just a combination of spaces/tabs## $goodnamespace=1; + }else{ + ## if stringlength is null then there were no charact +ers in the namespace ## $goodnamespace=0; } }else{ print "There is not a namespace delcared in the xmlfile.\n"; + ## edit when added to final program ## } if ($namespacedeclared==1 && $goodnamespace==1) { + ## if a namespace is declared and if that namespace is + good ## my $doc = XML::LibXML->load_xml(string => $xmlfile); print "Setting the namespace. And processing the XML.\n"; + ## edit when added to final program ## my $xc = XML::LibXML::XPathContext->new( $doc->documentElement +() ); $xc->registerNs( pfx => $namespace ); + ## sets the namespace prefix to $namespace ## my @events = $xc->findnodes('//pfx:EventInfo'); + foreach my $event (@events) { my $id = $xc->findvalue('pfx:EventId', $event); print "EventId: $id\n"; my @packs = $xc->findnodes('pfx:PreshowPackList/pfx:Presho +wPack', $event); if ( not @packs ) { print "No Packs\n"; next; } for my $pack (@packs) { my $pack_id = $xc->findvalue('pfx:PackId', $pack) || " +No PackId"; print "PackId: $pack_id\n"; } } }elsif (!$namespace && $namespacedeclared==0) { + ## if namespace is null and there was not a +namespace declared ## my $doc = XML::LibXML->load_xml(string => $xmlfile); print "No namespace set. Processing XML without.\n"; + ## edit when added to final program ## my @events = $doc->findnodes('//EventInfo'); foreach my $event (@events) { my $id = $event->findvalue('./EventId'); print "EventId: $id\n"; my @packs = $event->findnodes('./PreshowPackList/PreshowPa +ck'); if ( not @packs ) { print "No Packs\n"; next; } for my $pack (@packs) { #print $pack; my $pack_id = $pack->findvalue('PackId') || "No PackId +"; print "PackId: $pack_id\n"; } } }elsif ($namespacedeclared==1 && $goodnamespace==0) { + ## namespace w +as declared, but was not a valid namespace, just combination of space +s/tabs ## print "There was a namepace set in the XML file but it is a nu +ll value. Unable to continue with current code.\n"; ## edit when ad +ded to final program ## #return (0); ## Will add back when pushed i +nto sub in main program ## } #return(1); ## will add back when pushe +d into main program ##
Re: XML Parsing Problems
by Anonymous Monk on Jun 08, 2015 at 22:48 UTC
      XML::SImple STATUS_OF_THIS_MODULE
      The use of this module in new code is discouraged. Other modules are a +vailable which provide more straightforward and consistent interfaces +. In particular, XML::LibXML is highly recommended. The major problems with this module are the large number of options an +d the arbitrary ways in which these options interact - often with une +xpected results. Patches with bug fixes and documentation fixes are welcome, but new fe +atures are unlikely to be added.
      There are no rules, there are no thumbs..
      Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      It's much easier to switch from XML::Simple to XML::Rules than to XML::LibXML. Basically all you need is to give XML::Rules::inferRulesFromExample a few example XMLs (make sure all tags that may be repeated actually are repeated at least in one xml and make sure tags that only have optional attributes do have a attribute at least once) or use XML::Rules::inferRulesFromDTD to produce a set of transformation rules and you end up with a data structure very similar to the one produced by XML::Simple, with the only important difference being its consistency.

      You can then tweak the rules to skip parts you are not interested in, (pre)process branches of the XML, etc.

      Jenda
      Enoch was right!
      Enjoy the last years of Rome.

Re: XML Parsing Problems
by thanos1983 (Parson) on Jun 09, 2015 at 00:48 UTC

    Hello taralon,

    Welcome to the forum, a few short tips before answering your question. First of all please please use the

    < code >

    < /code >

    code tags properly. There is a preview button before posting your question where you can see how your question/reply looks like before posting it.

    Second, it seems that you are not a beginner. Then why you do not try as much as possible before posting your question? By doing so you will learn the most out of programming and you will find so many useful information and examples online.

    I am not an expert on hashes, the opposite I would consider my self a beginner but I spend a big amount of time in order to learn how to solve your complicated hash response from the XML parser.

    At the end it is not that complicated.

    A few things that I noticed on your "example" code:

    You are using use File::Slurp; on your sample code. Do you really need it? I was you I would play around with open. But this is only my opinion if you prefer using modules this is another solution. I have modified my answer in a similar way.

    Before posting your XML file please please format your XML text. It makes difficult for the rest of us to understand how is split into pieces and what are the data that we want to extract.

    A nicely formatted question, always attract more answers from the rest of the monks.

    So based on your code and data provided this is a possible solution to your question.

    #!/usr/bin/perl use strict; use warnings; use XML::Simple; use Data::Dumper; ## test script to verify the way xml is parsed## ## $xmlfile is set to data of a format that would be expected to be pa +ssed to this if used in a loop ## my $xmlfile = '<?xml version="1.0" encoding="UTF-8"?> <TMSMessage xmlns="http://xmlns.sony.net/d-cinema/tms-api/v1"> <MessageHeader> <Id>-1</Id> <Type>ListPerformances</Type> <Timestamp>1433796462559</Timestamp> <Source>TMS</Source> </MessageHeader> <MessageBody> <ListPerformancesResponse> <EventInfoList> <EventInfo> <EventId>2015060400000157</EventId> <EventTitle>zClosing Shutdown 3D v6 - New</EventTitle> <SplId>2010010100000038</SplId> <SplTitle>zClosing Shutdown 3D v6 - New</SplTitle> <AuditoriumId>15</AuditoriumId> <AuditoriumNo>15</AuditoriumNo> <EventStartTime>2015-06-08T00:30:00-07:00</EventStartTime> <DcpFlg>true</DcpFlg> <KdmFlg>true</KdmFlg> <EventDuration>464</EventDuration> <ShowStartTime>2015-06-08T00:30:00-07:00</ShowStartTime> <ShowDuration>464</ShowDuration> <SpokenLang></SpokenLang> <SubtitleLang></SubtitleLang> <Rating></Rating> <OverlappedEventFlg>false</OverlappedEventFlg> <UncompletedShowFlg>false</UncompletedShowFlg> <HavingShowFlg>true</HavingShowFlg> <EventBodyColor>696969</EventBodyColor> <ImportFlg>false</ImportFlg> <OverlappedNum>1</OverlappedNum> <HeightPos>0</HeightPos> <WaitGPIFlg>false</WaitGPIFlg> <EventEndTime>2015-06-08T00:37:44-07:00</EventEndTime> <ThreeDimension>true</ThreeDimension> <EventStatus>0</EventStatus> <ImportedShowId></ImportedShowId> <ImportedAnalogFlg>false</ImportedAnalogFlg> <EventRating></EventRating> <RatingFlg>true</RatingFlg> <PreshowPackList></PreshowPackList> </EventInfo> <!-- End of event info 1, start of event info 2 --> <EventInfo> <EventId>2015060400000164</EventId> <EventTitle>zMorning Startup 3D v3</EventTitle> <SplId>2011061100000013</SplId> <SplTitle>zMorning Startup 3D v3</SplTitle> <AuditoriumId>15</AuditoriumId> <AuditoriumNo>15</AuditoriumNo> <EventStartTime>2015-06-08T12:10:00-07:00</EventStartTime> <DcpFlg>true</DcpFlg> <KdmFlg>true</KdmFlg> <EventDuration>10</EventDuration> <ShowStartTime>2015-06-08T12:10:00-07:00</ShowStartTime> <ShowDuration>10</ShowDuration> <SpokenLang></SpokenLang> <SubtitleLang></SubtitleLang> <Rating></Rating> <OverlappedEventFlg>false</OverlappedEventFlg> <UncompletedShowFlg>false</UncompletedShowFlg> <HavingShowFlg>true</HavingShowFlg> <EventBodyColor>696969</EventBodyColor> <ImportFlg>false</ImportFlg> <OverlappedNum>1</OverlappedNum> <HeightPos>0</HeightPos> <WaitGPIFlg>false</WaitGPIFlg> <EventEndTime>2015-06-08T12:10:10-07:00</EventEndTime> <ThreeDimension>true</ThreeDimension> <EventStatus>0</EventStatus> <ImportedShowId></ImportedShowId> <ImportedAnalogFlg>false</ImportedAnalogFlg> <EventRating></EventRating> <RatingFlg>true</RatingFlg> <PreshowPackList></PreshowPackList> </EventInfo> <!-- End of event info 2, start of event info 3 --> <EventInfo> <EventId>2015060200000562</EventId> <EventTitle>* Movie1 3D-AV</EventTitle> <SplId>2015060800000048</SplId> <SplTitle>w23_3DP1_Sanandreas_SCCAP_0421pre_150605_02222_TMS_</SplTitl +e> <AuditoriumId>15</AuditoriumId> <AuditoriumNo>15</AuditoriumNo> <EventStartTime>2015-06-08T12:55:00-07:00</EventStartTime> <DcpFlg>true</DcpFlg> <KdmFlg>true</KdmFlg> <EventDuration>8195</EventDuration> <ShowStartTime>2015-06-08T12:29:18-07:00</ShowStartTime> <ShowDuration>9737</ShowDuration> <SpokenLang>en,en,en,en,en,en,en,en,en,en</SpokenLang> <SubtitleLang></SubtitleLang> <Rating>US-G US-G US-G US-G US-G US-G US-G US-G + US-G US-G </Rating> <OverlappedEventFlg>false</OverlappedEventFlg> <UncompletedShowFlg>false</UncompletedShowFlg> <HavingShowFlg>true</HavingShowFlg> <EventBodyColor>696969</EventBodyColor> <ImportFlg>true</ImportFlg> <OverlappedNum>1</OverlappedNum> <HeightPos>0</HeightPos> <WaitGPIFlg>false</WaitGPIFlg> <EventEndTime>2015-06-08T15:11:35-07:00</EventEndTime> <ThreeDimension>true</ThreeDimension> <EventStatus>0</EventStatus> <ImportedShowId>00343929</ImportedShowId> <ImportedAnalogFlg>false</ImportedAnalogFlg> <EventRating>US-13</EventRating> <RatingFlg>true</RatingFlg> <PreshowPackList> <PreshowPack> <PackId>b863a576-d8a3-4f5d-92a7-b66f876f6d7c</PackId> <FrameName>Preshow</FrameName> <FrameNumber>1</FrameNumber> </PreshowPack> <PreshowPack> <NoAssign>true</NoAssign> <FrameName>3D_Advertisement</FrameName> <FrameNumber>1</FrameNumber> </PreshowPack> <PreshowPack> <PackId>a55164d0-faa7-4c7c-a688-ed36011add95</PackId> <FrameName>Postshow</FrameName> <FrameNumber>1</FrameNumber> </PreshowPack> </PreshowPackList> </EventInfo> <!-- End of event info 3, start of event info 4 --> <EventInfo><EventId>2015060200000563</EventId> <EventTitle>* Movie1 3D-AV</EventTitle> <SplId>2015060600000017</SplId> <SplTitle>w23_3DP1_Sanandreas_SCCAP_0421pre_150605_02062_TMS_</SplTitl +e> <AuditoriumId>15</AuditoriumId> <AuditoriumNo>15</AuditoriumNo> <EventStartTime>2015-06-08T16:05:00-07:00</EventStartTime> <DcpFlg>true</DcpFlg> <KdmFlg>true</KdmFlg> <EventDuration>8195</EventDuration> <ShowStartTime>2015-06-08T15:42:13-07:00</ShowStartTime> <ShowDuration>9562</ShowDuration> <SpokenLang>en,en,en,en,en,en,en,en,en,en</SpokenLang> <SubtitleLang></SubtitleLang> <Rating>US-G US-G US-G US-G US-G US-G US-G US-G + US-G US-G </Rating> <OverlappedEventFlg>false</OverlappedEventFlg> <UncompletedShowFlg>false</UncompletedShowFlg> <HavingShowFlg>true</HavingShowFlg> <EventBodyColor>FFFFFF</EventBodyColor> <ImportFlg>true</ImportFlg> <OverlappedNum>1</OverlappedNum> <HeightPos>0</HeightPos> <WaitGPIFlg>false</WaitGPIFlg> <EventEndTime>2015-06-08T18:21:35-07:00</EventEndTime> <ThreeDimension>true</ThreeDimension> <EventStatus>0</EventStatus> <ImportedShowId>00343929</ImportedShowId> <ImportedAnalogFlg>false</ImportedAnalogFlg> <EventRating>US-13</EventRating> <RatingFlg>true</RatingFlg> <PreshowPackList> <PreshowPack> <PackId>760eb073-81f8-45cb-8553-484c5cecb740</PackId> <FrameName>Preshow</FrameName> <FrameNumber>1</FrameNumber> </PreshowPack> <PreshowPack> <NoAssign>true</NoAssign> <FrameName>3D_Advertisement</FrameName> <FrameNumber>1</FrameNumber> </PreshowPack> <PreshowPack> <PackId>a55164d0-faa7-4c7c-a688-ed36011add95</PackId> <FrameName>Postshow</FrameName> <FrameNumber>1</FrameNumber> </PreshowPack> </PreshowPackList> </EventInfo> </EventInfoList> </ListPerformancesResponse> </MessageBody> </TMSMessage>'; my $performancelist = XMLin( $xmlfile, ForceArray => 1, KeyAttr => { EventIn => 'EventId' } #ventID is a unique value that I want to use as a k +ey value ## ); #print Dumper $performancelist; my $filename = 'mydump.log'; open(my $fh, '>', $filename) or die "Could not open file '$filename' $!"; print $fh Dumper $performancelist; close $fh or die "Could not close file '$filename' $!"; foreach my $keys (keys $performancelist) { #print "\$keys: " . $keys . "\n"; foreach my $listPerformancesResponse ( keys $performancelist->{Mes +sageBody}[0] ) { #print $performancelist->{MessageBody}[0]->{$listPerformancesRespo +nse}[0] . "\n"; foreach my $eventInfoList (keys $performancelist->{MessageBody}[0] +->{$listPerformancesResponse}[0]) { # print Dumper $eventInfoList; foreach my $eventInfo (keys $performancelist->{MessageBody}[0] +->{$listPerformancesResponse}[0]->{$eventInfoList}[0]){ #print "\$eventInfo: " . $eventInfo . "\n"; foreach my $outputKeys (keys $performancelist->{MessageBody}[0 +]->{$listPerformancesResponse}[0]->{$eventInfoList}[0]->{$eventInfo}[ +0]){ print Dumper $outputKeys; } } } } } __DATA__ $VAR1 = 'ShowStartTime'; $VAR1 = 'RatingFlg'; $VAR1 = 'ImportedShowId'; $VAR1 = 'HeightPos'; $VAR1 = 'OverlappedNum'; $VAR1 = 'EventStatus'; $VAR1 = 'PreshowPackList'; $VAR1 = 'Rating'; $VAR1 = 'DcpFlg'; $VAR1 = 'SubtitleLang'; $VAR1 = 'HavingShowFlg'; $VAR1 = 'ThreeDimension'; $VAR1 = 'WaitGPIFlg'; $VAR1 = 'UncompletedShowFlg'; $VAR1 = 'EventTitle'; $VAR1 = 'ImportFlg'; $VAR1 = 'EventId'; $VAR1 = 'SplId'; $VAR1 = 'AuditoriumNo'; $VAR1 = 'EventRating'; $VAR1 = 'EventDuration'; $VAR1 = 'SplTitle'; $VAR1 = 'EventStartTime'; $VAR1 = 'OverlappedEventFlg'; $VAR1 = 'AuditoriumId'; $VAR1 = 'KdmFlg'; $VAR1 = 'ImportedAnalogFlg'; $VAR1 = 'EventBodyColor'; $VAR1 = 'ShowDuration'; $VAR1 = 'EventEndTime'; $VAR1 = 'SpokenLang'; $VAR1 = 'ShowStartTime'; $VAR1 = 'RatingFlg'; $VAR1 = 'ImportedShowId'; $VAR1 = 'HeightPos'; $VAR1 = 'OverlappedNum'; $VAR1 = 'EventStatus'; $VAR1 = 'PreshowPackList'; $VAR1 = 'Rating'; $VAR1 = 'DcpFlg'; $VAR1 = 'SubtitleLang'; $VAR1 = 'HavingShowFlg'; $VAR1 = 'ThreeDimension'; $VAR1 = 'WaitGPIFlg'; $VAR1 = 'UncompletedShowFlg'; $VAR1 = 'EventTitle'; $VAR1 = 'ImportFlg'; $VAR1 = 'EventId'; $VAR1 = 'SplId'; $VAR1 = 'AuditoriumNo'; $VAR1 = 'EventRating'; $VAR1 = 'EventDuration'; $VAR1 = 'SplTitle'; $VAR1 = 'EventStartTime'; $VAR1 = 'OverlappedEventFlg'; $VAR1 = 'AuditoriumId'; $VAR1 = 'KdmFlg'; $VAR1 = 'ImportedAnalogFlg'; $VAR1 = 'EventBodyColor'; $VAR1 = 'ShowDuration'; $VAR1 = 'EventEndTime'; $VAR1 = 'SpokenLang'; $VAR1 = 'ShowStartTime'; $VAR1 = 'RatingFlg'; $VAR1 = 'ImportedShowId'; $VAR1 = 'HeightPos'; $VAR1 = 'OverlappedNum'; $VAR1 = 'EventStatus'; $VAR1 = 'PreshowPackList'; $VAR1 = 'Rating'; $VAR1 = 'DcpFlg'; $VAR1 = 'SubtitleLang'; $VAR1 = 'HavingShowFlg'; $VAR1 = 'ThreeDimension'; $VAR1 = 'WaitGPIFlg'; $VAR1 = 'UncompletedShowFlg'; $VAR1 = 'EventTitle'; $VAR1 = 'ImportFlg'; $VAR1 = 'EventId'; $VAR1 = 'SplId'; $VAR1 = 'AuditoriumNo'; $VAR1 = 'EventRating'; $VAR1 = 'EventDuration'; $VAR1 = 'SplTitle'; $VAR1 = 'EventStartTime'; $VAR1 = 'OverlappedEventFlg'; $VAR1 = 'AuditoriumId'; $VAR1 = 'KdmFlg'; $VAR1 = 'ImportedAnalogFlg'; $VAR1 = 'EventBodyColor'; $VAR1 = 'ShowDuration'; $VAR1 = 'EventEndTime'; $VAR1 = 'SpokenLang';

    Update: I do not know if you still follow your post, but I was thinking about it over the last days so it came into my mind an alternative solution. Why you do not extract the data you want from the file that you write?

    Sample of code and output is provided under:

    #!/usr/bin/perl use strict; use warnings; use XML::Simple; use Data::Dumper; use List::MoreUtils qw( each_array ); ## test script to verify the way xml is parsed## ## $xmlfile is set to data of a format that would be expected to be pa +ssed to this if used in a loop ## my $xmlfile = '<?xml version="1.0" encoding="UTF-8"?> <TMSMessage xmlns="http://xmlns.sony.net/d-cinema/tms-api/v1"> <MessageHeader> <Id>-1</Id> <Type>ListPerformances</Type> <Timestamp>1433796462559</Timestamp> <Source>TMS</Source> </MessageHeader> <MessageBody> <ListPerformancesResponse> <EventInfoList> <EventInfo> <EventId>2015060400000157</EventId> <EventTitle>zClosing Shutdown 3D v6 - New</EventTitle> <SplId>2010010100000038</SplId> <SplTitle>zClosing Shutdown 3D v6 - New</SplTitle> <AuditoriumId>15</AuditoriumId> <AuditoriumNo>15</AuditoriumNo> <EventStartTime>2015-06-08T00:30:00-07:00</EventStartTime> <DcpFlg>true</DcpFlg> <KdmFlg>true</KdmFlg> <EventDuration>464</EventDuration> <ShowStartTime>2015-06-08T00:30:00-07:00</ShowStartTime> <ShowDuration>464</ShowDuration> <SpokenLang></SpokenLang> <SubtitleLang></SubtitleLang> <Rating></Rating> <OverlappedEventFlg>false</OverlappedEventFlg> <UncompletedShowFlg>false</UncompletedShowFlg> <HavingShowFlg>true</HavingShowFlg> <EventBodyColor>696969</EventBodyColor> <ImportFlg>false</ImportFlg> <OverlappedNum>1</OverlappedNum> <HeightPos>0</HeightPos> <WaitGPIFlg>false</WaitGPIFlg> <EventEndTime>2015-06-08T00:37:44-07:00</EventEndTime> <ThreeDimension>true</ThreeDimension> <EventStatus>0</EventStatus> <ImportedShowId></ImportedShowId> <ImportedAnalogFlg>false</ImportedAnalogFlg> <EventRating></EventRating> <RatingFlg>true</RatingFlg> <PreshowPackList></PreshowPackList> </EventInfo> <!-- End of event info 1, start of event info 2 --> <EventInfo> <EventId>2015060400000164</EventId> <EventTitle>zMorning Startup 3D v3</EventTitle> <SplId>2011061100000013</SplId> <SplTitle>zMornnning Startup 3D v3</SplTitle> <AuditoriumId>15</AuditoriumId> <AuditoriumNo>15</AuditoriumNo> <EventStartTime>2015-06-08T12:10:00-07:00</EventStartTime> <DcpFlg>true</DcpFlg> <KdmFlg>true</KdmFlg> <EventDuration>10</EventDuration> <ShowStartTime>2015-06-08T12:10:00-07:00</ShowStartTime> <ShowDuration>10</ShowDuration> <SpokenLang></SpokenLang> <SubtitleLang></SubtitleLang> <Rating></Rating> <OverlappedEventFlg>false</OverlappedEventFlg> <UncompletedShowFlg>false</UncompletedShowFlg> <HavingShowFlg>true</HavingShowFlg> <EventBodyColor>696969</EventBodyColor> <ImportFlg>false</ImportFlg> <OverlappedNum>1</OverlappedNum> <HeightPos>0</HeightPos> <WaitGPIFlg>false</WaitGPIFlg> <EventEndTime>2015-06-08T12:10:10-07:00</EventEndTime> <ThreeDimension>true</ThreeDimension> <EventStatus>0</EventStatus> <ImportedShowId></ImportedShowId> <ImportedAnalogFlg>false</ImportedAnalogFlg> <EventRating></EventRating> <RatingFlg>true</RatingFlg> <PreshowPackList></PreshowPackList> </EventInfo> <!-- End of event info 2, start of event info 3 --> <EventInfo> <EventId>2015060200000562</EventId> <EventTitle>* Movie1 3D-AV</EventTitle> <SplId>2015060800000048</SplId> <SplTitle>w23_3DP1_Sanandreas_SCCAP_0421pre_150605_02222_TMS_</SplTitl +e> <AuditoriumId>15</AuditoriumId> <AuditoriumNo>15</AuditoriumNo> <EventStartTime>2015-06-08T12:55:00-07:00</EventStartTime> <DcpFlg>true</DcpFlg> <KdmFlg>true</KdmFlg> <EventDuration>8195</EventDuration> <ShowStartTime>2015-06-08T12:29:18-07:00</ShowStartTime> <ShowDuration>9737</ShowDuration> <SpokenLang>en,en,en,en,en,en,en,en,en,en</SpokenLang> <SubtitleLang></SubtitleLang> <Rating>US-G US-G US-G US-G US-G US-G US-G US-G + US-G US-G </Rating> <OverlappedEventFlg>false</OverlappedEventFlg> <UncompletedShowFlg>false</UncompletedShowFlg> <HavingShowFlg>true</HavingShowFlg> <EventBodyColor>696969</EventBodyColor> <ImportFlg>true</ImportFlg> <OverlappedNum>1</OverlappedNum> <HeightPos>0</HeightPos> <WaitGPIFlg>false</WaitGPIFlg> <EventEndTime>2015-06-08T15:11:35-07:00</EventEndTime> <ThreeDimension>true</ThreeDimension> <EventStatus>0</EventStatus> <ImportedShowId>00343929</ImportedShowId> <ImportedAnalogFlg>false</ImportedAnalogFlg> <EventRating>US-13</EventRating> <RatingFlg>true</RatingFlg> <PreshowPackList> <PreshowPack> <PackId>b863a576-d8a3-4f5d-92a7-b66f876f6d7c</PackId> <FrameName>Preshow</FrameName> <FrameNumber>1</FrameNumber> </PreshowPack> <PreshowPack> <NoAssign>true</NoAssign> <FrameName>3D_Advertisement</FrameName> <FrameNumber>1</FrameNumber> </PreshowPack> <PreshowPack> <PackId>a55164d0-faa7-4c7c-a688-ed36011add95</PackId> <FrameName>Postshow</FrameName> <FrameNumber>1</FrameNumber> </PreshowPack> </PreshowPackList> </EventInfo> <!-- End of event info 3, start of event info 4 --> <EventInfo><EventId>2015060200000563</EventId> <EventTitle>* Movie1 3D-AV</EventTitle> <SplId>2015060600000017</SplId> <SplTitle>w23_3DP1_Sanandreas_SCCAP_0421pre_150605_02062_TMS_</SplTitl +e> <AuditoriumId>15</AuditoriumId> <AuditoriumNo>15</AuditoriumNo> <EventStartTime>2015-06-08T16:05:00-07:00</EventStartTime> <DcpFlg>true</DcpFlg> <KdmFlg>true</KdmFlg> <EventDuration>8195</EventDuration> <ShowStartTime>2015-06-08T15:42:13-07:00</ShowStartTime> <ShowDuration>9562</ShowDuration> <SpokenLang>en,en,en,en,en,en,en,en,en,en</SpokenLang> <SubtitleLang></SubtitleLang> <Rating>US-G US-G US-G US-G US-G US-G US-G US-G + US-G US-G </Rating> <OverlappedEventFlg>false</OverlappedEventFlg> <UncompletedShowFlg>false</UncompletedShowFlg> <HavingShowFlg>true</HavingShowFlg> <EventBodyColor>FFFFFF</EventBodyColor> <ImportFlg>true</ImportFlg> <OverlappedNum>1</OverlappedNum> <HeightPos>0</HeightPos> <WaitGPIFlg>false</WaitGPIFlg> <EventEndTime>2015-06-08T18:21:35-07:00</EventEndTime> <ThreeDimension>true</ThreeDimension> <EventStatus>0</EventStatus> <ImportedShowId>00343929</ImportedShowId> <ImportedAnalogFlg>false</ImportedAnalogFlg> <EventRating>US-13</EventRating> <RatingFlg>true</RatingFlg> <PreshowPackList> <PreshowPack> <PackId>760eb073-81f8-45cb-8553-484c5cecb740</PackId> <FrameName>Preshow</FrameName> <FrameNumber>1</FrameNumber> </PreshowPack> <PreshowPack> <NoAssign>true</NoAssign> <FrameName>3D_Advertisement</FrameName> <FrameNumber>1</FrameNumber> </PreshowPack> <PreshowPack> <PackId>a55164d0-faa7-4c7c-a688-ed36011add95</PackId> <FrameName>Postshow</FrameName> <FrameNumber>1</FrameNumber> </PreshowPack> </PreshowPackList> </EventInfo> </EventInfoList> </ListPerformancesResponse> </MessageBody> </TMSMessage>'; my $performancelist = XMLin( $xmlfile, ForceArray => 1, KeyAttr => { EventIn => 'EventId' } #ventID is a unique value that I want to use as a k +ey value ## ); #print Dumper $performancelist; my $filename = 'mydump.log'; open(my $fhWrite, '>', $filename) or die "Could not open file '$filename' $!"; print $fhWrite Dumper $performancelist; close $fhWrite or die "Could not close file '$filename' $!"; my (@frameNamelinesContainData,@packIdlinesContainData); open(my $fhRead, '<', $filename) or die "Could not open file '$filename' $!"; my @dataArray = <$fhRead>; my $lineNumber = 0; foreach my $line (@dataArray) { $lineNumber++; if ($line =~ /FrameName/) { push @frameNamelinesContainData , $lineNumber; } elsif ($line =~ /PackId/) { push @packIdlinesContainData , $lineNumber; } } close $fhRead or die "Could not close file '$filename' $!"; splice @frameNamelinesContainData, 1, 1; splice @frameNamelinesContainData, 3, 1; my %output; my $ea = each_array( @frameNamelinesContainData, @packIdlinesContainDa +ta ); while ( my( $a, $b ) = $ea->() ) { $dataArray[$a] =~ s/^\s+|\s+$//g; $dataArray[$b] =~ s/^\s+|\s+$//g; $output{'FrameName'}{$dataArray[$b]} = $dataArray[$a]; } print Dumper \%output; __DATA__ $VAR1 = { 'FrameName' => { '\'b863a576-d8a3-4f5d-92a7-b66f876f6d7c\'' +=> '\'Preshow\'', '\'a55164d0-faa7-4c7c-a688-ed36011add95\'' +=> '\'Postshow\'', '\'760eb073-81f8-45cb-8553-484c5cecb740\'' +=> '\'Preshow\'' } };

    Hope this helps.

    Seeking for Perl wisdom...on the process of learning...not there...yet!