我需要将XML节点元素提取到CSV

我需要将XML节点元素提取到CSV,xml,perl,csv,Xml,Perl,Csv,=XML文件= <?xml version="1.0" encoding="utf-8"?> <weatherdata> <location> <name>Toronto</name> <type/> <country>CA</country> <timezone/> <location altitude="0" latitude="43.700111" longitude=

=XML文件=

    <?xml version="1.0" encoding="utf-8"?>
<weatherdata>
<location>
<name>Toronto</name>
<type/>
<country>CA</country>
<timezone/>
<location altitude="0" latitude="43.700111" longitude="-79.416298" geobase="geonames" geobaseid="0"/></location>
<credit/>
 <meta>
<lastupdate/>
  <calctime>1.4906</calctime>
<nextupdate/>
 </meta>
 <sun rise="2015-02-17T12:12:32" set="2015-02-17T22:50:42"/>
<forecast>
<time from="2015-02-17T15:00:00" to="2015-02-17T18:00:00">
  <symbol number="803" name="broken clouds" var="04d"/>
  <precipitation/>
  <windDirection deg="43.5048" code="NE" name="NorthEast"/>
  <windSpeed mps="1.82" name="Light breeze"/>
  <temperature unit="celsius" value="-13.29" min="-13.293" max="-13.29"/>
  <pressure unit="hPa" value="1007.77"/>
  <humidity value="100" unit="%"/>
  <clouds value="broken clouds" all="64" unit="%"/>
</time>
<time from="2015-02-17T18:00:00" to="2015-02-17T21:00:00">
  <symbol number="803" name="broken clouds" var="04d"/>
  <precipitation/>
  <windDirection deg="255.501" code="WSW" name="West-southwest"/>
  <windSpeed mps="0.66" name="Calm"/>
  <temperature unit="celsius" value="-10.16" min="-10.16" max="-10.16"/>
  <pressure unit="hPa" value="1006.44"/>
  <humidity value="100" unit="%"/>
  <clouds value="broken clouds" all="80" unit="%"/>
</time>
我希望从XML文件中提取:

“从”只是时间 “湿度值”值 “最高温度”温度值 “最低温度”温度值 “压力值”为hpA值

下面的代码是我的草稿代码,以查看我是否在正确的轨道上。目的是让它与几个节点一起工作;将其输出到CSV文件。我哪儿也去不了

=PERL代码=

use strict;

use Data::Dumper;
use XML::Simple 'XMLin';

my $input_xml = '/var/egridmanage_pl/data/longrange.xml' ||die $!;
my $output_csv = '/var/egridmanage_pl/longrange.csv';

my $parse = XMLin('/var/egridmanage_pl/data/longrange.xml',forcearray => ['value']);

foreach my $dataset (@{$parse->{weatherdata}}) {
if ($dataset->{name} eq 'Toronto') {
    open my $out, ">", $output_csv or die "Could not open $output_csv: $!";
print {$out} $dataset->{att}-> {from} . "\n";
print {$out} $dataset->{att}->[0]->{value} . "\n";
}
}
=预期结果如下=我需要帮助

time      | humidity |  hPa    | min    | max    |

15:00:00  | 100      | 1007.77 | -13.29 | -13.29 | 

让我提出一些完全不同的建议。因为您的输入是XML文档,所以可以使用XSLT从中提取数据

然后,Perl代码将包括执行此转换,其他所有内容都将在XSLT样式表中处理。您必须使用包含XSLT处理器的库,在我看来,使用LibXML和LibXSLT将是从以下示例代码中获取的最安全的方法:

假设输入XML格式良好,请使用以下转换

XSLT样式表


让我提出一些完全不同的建议。因为您的输入是XML文档,所以可以使用XSLT从中提取数据

然后,Perl代码将包括执行此转换,其他所有内容都将在XSLT样式表中处理。您必须使用包含XSLT处理器的库,在我看来,使用LibXML和LibXSLT将是从以下示例代码中获取的最安全的方法:

假设输入XML格式良好,请使用以下转换

XSLT样式表


虽然您有一个答案,但您已经将其标记为Perl,因此我将提供一些perlish。首先,不要使用。从它的文档:

不鼓励在新代码中使用此模块。还提供了其他模块,它们提供了更直观和一致的接口

我个人喜欢XML解析。它是这样的:注意——我已经减少了您的XML,因为您的XML不完整,因此无效。但这不重要,因为这段代码只检查元素


虽然您有一个答案,但您已经将其标记为Perl,因此我将提供一些perlish。首先,不要使用。从它的文档:

不鼓励在新代码中使用此模块。还提供了其他模块,它们提供了更直观和一致的接口

我个人喜欢XML解析。它是这样的:注意——我已经减少了您的XML,因为您的XML不完整,因此无效。但这不重要,因为这段代码只检查元素


您介意给我们提供格式良好的XML吗?我喜欢帮忙。我不喜欢跟踪XML中的开放元素,以便最终解析它并帮助您。谢谢:XML::Simple在撒谎。这并不简单,它是用于简单的XML。新代码不建议使用它。您介意给我们提供格式良好的XML吗?我喜欢帮忙。我不喜欢跟踪XML中的开放元素,以便最终解析它并帮助您。谢谢:XML::Simple在撒谎。这并不简单,它是用于简单的XML。新代码不建议使用它。天哪!我没想到会有如此迅速和全面的反应。非常感谢,穆勒!!神圣的我没想到会有如此迅速和全面的反应。非常感谢,穆勒!!但是,对于大文件,IIRC,使用细枝根可能更好。。。顺便说一句,从什么时候开始禁止在评论中使用简单的+1?!我不确定twig_根-但我已经成功地使用了大型XML,只需在处理程序中清除即可。twig_handlers/purge应该可以,除非两个时间元素之间有大量未使用的XML,在这种情况下,使用twig_根可以避免将其加载到内存中。但是,对于大型文件,IIRC,使用twig_根可能更好。。。顺便说一句,从什么时候开始禁止在评论中使用简单的+1?!不确定twig_根-但我已经成功地使用了大型XML并在处理程序中进行了简单的清除。twig_handlers/purge应该可以,除非两个时间元素之间有大量未使用的XML,在这种情况下,使用twig_根可以避免将其加载到内存中。
time      | humidity |  hPa    | min    | max    |

15:00:00  | 100      | 1007.77 | -13.29 | -13.29 | 
use XML::LibXSLT;
use XML::LibXML;

my $xslt = XML::LibXSLT->new();

my $source = XML::LibXML->load_xml(location => 'foo.xml');
my $style_doc = XML::LibXML->load_xml(location=>'bar.xsl', no_cdata=>1);

my $stylesheet = $xslt->parse_stylesheet($style_doc);

my $results = $stylesheet->transform($source);

print $stylesheet->output_as_bytes($results);
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="text" encoding="UTF-8" />

    <xsl:strip-space elements="*"/>

    <xsl:template match="/">
        <xsl:text>time|humidity|hPa|min|max|&#xA;</xsl:text>
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="time">
        <xsl:value-of select="concat(@from,'|',humidity/@value, '|', pressure/@value,'|', temperature/@min, '|', temperature/@max, '|')"/>
        <xsl:if test="following::time">
            <xsl:text>&#xA;</xsl:text>
        </xsl:if>
    </xsl:template>

    <xsl:template match="text()"/>

</xsl:transform>
time|humidity|hPa|min|max|
2015-02-17T15:00:00|100|1007.77|-13.293|-13.29|
2015-02-17T18:00:00|100|1006.44|-10.16|-10.16|
#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

sub time_handler {
    my ( $twig, $time ) = @_;

    print join( "\t",
        $time->att('from'),
        $time->first_child('humidity')->att('value'),
        $time->first_child('pressure')->att('value'),
        $time->first_child('temperature')->att('min'),
        $time->first_child('temperature')->att('max'),
        "\n" );

    #will discard data as you go, saving memory footprint.  
    $twig -> purge;    
}

local $/;
my $parser = XML::Twig->new( twig_handlers => { 'time' => \&time_handler } )
    ->parse(<DATA>);

__DATA__
<?xml version="1.0" encoding="utf-8"?>
<weatherdata>
<time from="2015-02-17T15:00:00" to="2015-02-17T18:00:00">
  <symbol number="803" name="broken clouds" var="04d"/>
  <precipitation/>
  <windDirection deg="43.5048" code="NE" name="NorthEast"/>
  <windSpeed mps="1.82" name="Light breeze"/>
  <temperature unit="celsius" value="-13.29" min="-13.293" max="-13.29"/>
  <pressure unit="hPa" value="1007.77"/>
  <humidity value="100" unit="%"/>
  <clouds value="broken clouds" all="64" unit="%"/>
</time>
<time from="2015-02-17T18:00:00" to="2015-02-17T21:00:00">
  <symbol number="803" name="broken clouds" var="04d"/>
  <precipitation/>
  <windDirection deg="255.501" code="WSW" name="West-southwest"/>
  <windSpeed mps="0.66" name="Calm"/>
  <temperature unit="celsius" value="-10.16" min="-10.16" max="-10.16"/>
  <pressure unit="hPa" value="1006.44"/>
  <humidity value="100" unit="%"/>
  <clouds value="broken clouds" all="80" unit="%"/>
</time>
</weatherdata>