Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Re: How to use perl to parsing a XML file to csv file which have the same sequence in xml file?

by tobyink (Abbot)
on Jun 14, 2012 at 12:01 UTC ( #976188=note: print w/ replies, xml ) Need Help??


in reply to How to use perl to parsing a XML file to csv file which have the same sequence in xml file?

In you care about the order of those elements XML::Simple (or indeed any similar XML-to-hashref tool) is not your friend. Perl hashes do not preserve order. There are modules that give you order-preserving hashes (via ties) but persuading XML::Simple to use them is probably not possible.

use PerlX::MethodCallWithBlock; use Text::CSV; use XML::LibXML 1.94; local $\ = "\n"; my $xml = XML::LibXML->load_xml(IO => \*DATA); my $csv = Text::CSV->new; foreach my $book ($xml->findnodes('/library/book')) { my $row = $book->findnodes('./*')->map{ $_->textContent }; $csv->print(\*STDOUT, $row); } __DATA__ <library> <book> <author>Book 1 author 1</author> <author>Book 1 author 2</author> <title>Book 1 title</title> <isbn>Book1ISBN</isbn> </book> <book> <author>Book 2 author 1</author> <author>Book 2 author 2</author> <title>Book 2 title</title> <isbn>Book2ISBN</isbn> </book> </library>

The output from the above is:

"Book 1 author 1","Book 1 author 2","Book 1 title",Book1ISBN
"Book 2 author 1","Book 2 author 2","Book 2 title",Book2ISBN
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'


Comment on Re: How to use perl to parsing a XML file to csv file which have the same sequence in xml file?
Download Code
Re^2: How to use perl to parsing a XML file to csv file which have the same sequence in xml file?
by Anonymous Monk on Dec 28, 2012 at 22:25 UTC
    Hello

    I tried to run the example provided here, and I get the following error:

     Expected fields to be an array ref at xml.pl line 11

    When I look at the contents of $book, I see:

    $VAR1 = bless( [ 'Book 1 author 1', 'Book 1 author 2', 'Book 1 title', 'Book1ISBN' ], 'XML::LibXML::NodeList' ); $VAR1 = bless( [ 'Book 2 author 1', 'Book 2 author 2', 'Book 2 title', 'Book2ISBN' ], 'XML::LibXML::NodeList' );
    I am running perl 5.10.1 -- any tips?

      I am running perl 5.10.1 -- any tips?

      Forget it, its magic :) I get

      PL_linestr not long enough, was Devel::Declare loaded soon enough in f +udge at PerlX/MethodCallWithBlock.pm line 107.

      Report it to PerlX::MethodCallWithBlock maintainer

      It worked on my machine, but Text::CSV's behaviour can be a little variable - it has two underlying implementations: one in pure Perl, and a faster one in C. Which one you get is the luck of the draw. In this case, $row is a blessed arrayref; Text::CSV expects an arrayref; it looks like one of the implementations rejects the arrayref if it's blessed but the other does not.

      $csv->print(\*STDOUT, [@$row]); # unblessed shallow clone of $row
      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
        Hah, its the PP version that is too picky :)
        $ perl -MText::CSV_PP -e " Text::CSV_PP->new->print(\*STDOUT, [1..3] ) + " 1,2,3 $ perl -MText::CSV_XS -e " Text::CSV_XS->new->print(\*STDOUT, [1..3] ) + " 1,2,3 $ perl -MText::CSV_XS -e " Text::CSV_XS->new->print(\*STDOUT, bless[1. +.3],666 ) " 1,2,3 $ perl -MText::CSV_PP -e " Text::CSV_PP->new->print(\*STDOUT, bless[1. +.3],666 ) " Expected fields to be an array ref at -e line 1.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://976188]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (12)
As of 2014-10-21 19:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (106 votes), past polls