xml - Perl XML::LibXML,findnodes只能读取XML文件的根目录

标签 xml perl nodes xml-libxml

我正在尝试解析此 .kml 文件:

<?xml version="1.0" encoding="utf-8" ?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document id="root_doc">
<Schema name="PostalCodeCanada" id="PostalCodeCanada">
    <SimpleField name="ZIP" type="string"></SimpleField>
    <SimpleField name="VERTICES" type="int"></SimpleField>
</Schema>
<Folder><name>PostalCodeCanada</name>
  <Placemark>
    <Style><LineStyle><color>ff0000ff</color></LineStyle><PolyStyle><fill>0</fill></PolyStyle></Style>
    <ExtendedData><SchemaData schemaUrl="#PostalCodeCanada">
        <SimpleData name="ZIP">G1Y1B1</SimpleData>
        <SimpleData name="VERTICES">5</SimpleData>
    </SchemaData></ExtendedData>
      <Polygon><altitudeMode>relativeToGround</altitudeMode><outerBoundaryIs><LinearRing><altitudeMode>relativeToGround</altitudeMode><coordinates>-73.604399,45.545611 -73.603988,45.545886 -73.602861,45.547715 -73.602861,45.547715 -73.604399,45.545611 -73.604399,45.545611</coordinates></LinearRing></outerBoundaryIs></Polygon>
  </Placemark>
  <Placemark>
    <Style><LineStyle><color>ff0000ff</color></LineStyle><PolyStyle><fill>0</fill></PolyStyle></Style>
    <ExtendedData><SchemaData schemaUrl="#PostalCodeCanada">
        <SimpleData name="ZIP">G1Y1B2</SimpleData>
        <SimpleData name="VERTICES">5</SimpleData>
    </SchemaData></ExtendedData>
      <Polygon><altitudeMode>relativeToGround</altitudeMode><outerBoundaryIs><LinearRing><altitudeMode>relativeToGround</altitudeMode><coordinates>-73.604399,45.545611 -73.603988,45.545886 -73.602861,45.547715 -73.602861,45.547715 -73.604399,45.545611 -73.604399,45.545611</coordinates></LinearRing></outerBoundaryIs></Polygon>
  </Placemark>
</Folder>
</Document></kml>

我将 Perl 与 XML::LibXML 结合使用,但 findnodes 无法读取除“/”之外的任何节点。这是我的代码:

#!/usr/bin/env perl

use XML::LibXML;
use strict;
use warnings;

my $outputFilename = "PostalCodesCollegePro.kml";

my $intro = '<?xml version="1.0" encoding="utf-8" ?>'."\n".'<kml xmlns="http://www.opengis.net/kml/2.2">'."\n".'<Document id="root_doc">'."\n".'<Schema name="PostalCodeCanada" id="PostalCodeCanada">'."\n\t".'<SimpleField name="ZIP" type="string"></SimpleField>'."\n\t".'<SimpleField name="VERTICES" type="int"></SimpleField>'."\n".'</Schema>'."\n".'<Folder><name>PostalCodeCanada</name>'."\n";
my $outro = '</Folder>'."\n".'</Document></kml>'."\n";

open (my $fh, ">".$outputFilename) or die "Impossible d'ouvrir le fichier d'écriture";
print $fh $intro;

my $xml = XML::LibXML->new();
my $data = $xml->parse_file("PostalCodeCanada.kml");
foreach my $node ( $data->findnodes('//Folder') ) {
    print ($node->toString);
#   my($zip) = $node->findnodes('./ExtendedData/SchemaData/SimpleData');
#   print ($zip->to_literal."\n");
#   if ($zip->to_literal =~ /(^G1Y)|(^G3A)|(^G2G)|(^G3L)|(^G3H)|G0A2R0|G0A1T0|G0A1L0|G0A3H0|G0A3G0|G0A2Y0|G0A2Z0|G0A4N0|G0A2J0|G0A3M0|G0A4A0|G0A1A0|G0A1Y0|G0A1S0|G0A4B0|G0A3T0|G0A3B0|G0A4H0|G0A1W0|G0A3L0|G0A4L0|G0A3A0/){
#       print $fh $node->to_literal;
#   }
}

print $fh $outro; 
close $fh or warn "Impossible de fermer le fichier après écriture";`

感谢所有提供帮助的人! PS:这是一个缩小的.kml 文件,实际上真正的文件包含所有加拿大邮政编码的所有地理信息。我正在尝试生成另一个仅包含所需邮政编码的 .kml,以便使用 Google Map API 生成 map 。

最佳答案

你的问题是你的节点都在一个命名空间内,所以你需要处理这个问题。最简单的方法可能是使用 XML::LibXML::XPathContext对象。

my $xml = XML::LibXML->new();
my $data = $xml->parse_file("PostalCodeCanada.kml");

my $xpc = XML::LibXML::XPathContext->new($data);
$xpc->registerNs('k', 'http://www.opengis.net/kml/2.2');

foreach my $node ( $xpc->findnodes('//k:Folder') ) {
  ...
}

关于xml - Perl XML::LibXML,findnodes只能读取XML文件的根目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34484778/

相关文章:

java - 使用 JAXB 将 XML CDATA 字符串解码为文字

docker - Docker Swarm上的Hadoop集群-数据节点无法连接到Namenode

C 列表 - 访问结构体的成员并打印它

c - 在c中设计这个结构的最佳方法是什么?

xml - 在 Go 中将通用 csv 转换为 xml

xml - Groovys XmlSlurper 中的命名空间处理

android - 如何在android Lollipop的xml中添加RecyclerView

perl - printf "Modification of a read-only value attempted"错误

regex - 如何在不使用 json 库和 json 解析器的情况下解析 json 文件

perl - 使用 Perl 的 3D 立方体中的点或球体