1

我一直在试图弄清楚如何将 xml 数据源解析为 CSV 文件,这让我有点抓狂。我有一个数据源,我需要解析并创建一个 CSV。我还需要能够将节点 ID 作为一列包含在内。这是我所拥有的:

         #!/usr/bin/perl
            use warnings;
        use strict;
        use XML::XPath;

        #Name of the CSV File
        my $filename = "parse.csv";

        #Create the file.
        open(INPUT,">$filename") or die "Cannot create file";

        #Collect the XML and set nodes
        my($xp) = XML::XPath->new( join('', <DATA>) );
        my(@records) = $xp->findnodes( '/CATALOG/CD' );
        my($firstTime) = 0;

        #Loop through each record
        foreach my $record ( @records ) {
            my(@fields) = $xp->find( './child::*', $record )->get_nodelist();
            unless ( $firstTime++ ) {
            #Print Headers
                print( join( ',', map { $_->getName() } @fields ), "\n");
            }
            #Print Content
                print( join( ',', map { $_->string_value() } @fields ), "\n");
        }
        #Close the file.
        close(INPUT);


        __DATA__
        <FOOD>
            <ITEM id='1'>
                <Color>Brown</Color>
                <Name>Steak</Name>
            </ITEM>
            <ITEM id='2'>
                <Color>Blue</Color>
                <Name>Blueberries</Name>
            </ITEM>
            <ITEM id='3'>
                <Color>Red</Color>
                <Name>Apple</Name>
            </ITEM>
        </FOOD>

它创建了一个 CSV,但它是空的,我认为这是因为 foreach 循环中的打印行。

任何帮助将不胜感激!

4

3 回答 3

2

鉴于 XML 模式的简单性,这更容易做到AnyData

例如:

#!/usr/bin/perl
# This script converts a XML file to CSV format.

# Load the AnyData XML to CSV conversion modules
use XML::Parser;
use XML::Twig;
use AnyData;

my $input_xml = "test.xml";
my $output_csv = "test.csv";


$flags->{record_tag} = 'ITEM';
adConvert( 'XML', $input_xml, 'CSV', $output_csv, $flags );

将您的数据结构 (XML) 转换为:

id,Color,Name
1,Brown,Steak
2,Blue,Blueberries
3,Red,Apple
于 2013-11-08T10:49:20.167 回答
2

您正在将标题和内容打印到标准输出,而不是输出文件。您需要将文件句柄作为第一个参数传递给它和要打印的内容之间print 没有逗号。就像是:print FILE join(',', ...), "\n";

我还建议不要将INPUT其用作您要输出到的文件句柄 - 这会使理解代码有点混乱。

于 2013-09-23T22:13:33.543 回答
1

在您的情况下,您使用的是 /CATALOG/CD 而不是您的数据。请使用类似的东西

my(@records) = $xp->findnodes( '/FOOD/ITEM' );
....
...
...
print INPUT ( join( ',', map { $_->getName() } @fields ), "\n" );
于 2015-11-23T09:43:30.923 回答