in reply to XML parsing

This does nearly what you want:

use strict; use XML::Simple; my $xml = <<EOX; <FinInstnCdtTrf> <GrpHdr> <MsgId>0000003714</MsgId> <CreDtTm>2013-03-04T16:01:57</CreDtTm> <NbOfTxs>1</NbOfTxs> <TtlIntrBkSttlmAmt Ccy="INR">234.00</TtlIntrBkSttlmAmt> <IntrBkSttlmDt>2013-02-05</IntrBkSttlmDt> <SttlmInf> <SttlmMtd>CLRG</SttlmMtd> </SttlmInf> <InstgAgt> <FinInstnId> <ClrSysMmbId> <MmbId>HOMEMEMEBER</MmbId> </ClrSysMmbId> </FinInstnId> </InstgAgt> <InstdAgt> <FinInstnId> <ClrSysMmbId> <MmbId>FOREIGNMEMBER</MmbId> </ClrSysMmbId> </FinInstnId> </InstdAgt> </GrpHdr> </FinInstnCdtTrf> EOX sub parsetree { my $ref = shift; my $txt = shift; foreach my $key ( keys %{$ref} ) { if( ref( $$ref{$key} ) =~ /HASH/ ) { parsetree( $$ref{$key}, $txt."::".$key ); } else { print $txt."::".$key."::".$$ref{$key}."\n"; } } } parsetree(XMLin($xml));

Output:

::GrpHdr::InstgAgt::FinInstnId::ClrSysMmbId::MmbId::HOMEMEMEBER ::GrpHdr::IntrBkSttlmDt::2013-02-05 ::GrpHdr::NbOfTxs::1 ::GrpHdr::SttlmInf::SttlmMtd::CLRG ::GrpHdr::TtlIntrBkSttlmAmt::Ccy::INR ::GrpHdr::TtlIntrBkSttlmAmt::content::234.00 ::GrpHdr::CreDtTm::2013-03-04T16:01:57 ::GrpHdr::InstdAgt::FinInstnId::ClrSysMmbId::MmbId::FOREIGNMEMBER ::GrpHdr::MsgId::0000003714

Replies are listed 'Best First'.
Re^2: XML parsing
by davido (Cardinal) on Mar 25, 2013 at 08:50 UTC

    A quick and dirty fix is to just strip off any leading "::" before printing:

    sub parsetree { my $ref = shift; my $txt = shift; foreach my $key ( keys %{$ref} ) { if( ref( $$ref{$key} ) =~ /HASH/ ) { parsetree( $$ref{$key}, $txt."::".$key ); } else { my $out = $txt . '::' . $key . '::' . $$ref{$key} . "\n"; $out =~ s/^:://; print $out; } } }

    This will produce (Update: closer to) the requested output, so long as "order" doesn't matter.


    Dave

      There is one more difference to the requested output. The currency (INR) and the amount (234.00) are given as separate lines. This results from the way XML::Simple deals with <tag name=value>.