1

我有一个与 Google 地球导出的 KML 相关的问题,因为它似乎不适用于 Element Tree。我不知道问题可能出在哪里,所以我将解释我如何做所有事情。

以下是相关代码:

    kmlFile = open( filePath, 'r' ).read( -1 ) # read the whole file as text
    kmlFile = kmlFile.replace( 'gx:', 'gx' )   # we need this as otherwise the Element Tree parser
                                               # will give an error

    kmlData = ET.fromstring( kmlFile )
    document = kmlData.find( 'Document' )

使用此代码,ET(元素树对象)创建一个可通过变量 kmlData 访问的元素对象。它指向根元素('kml' 标签)。但是,当我搜索子元素“文档”时,它返回无。尽管“文档”标签存在于 KML 文件中!

除了“gx: smth”标签之外,KML 和 XML 之间是否还有其他差异?我搜索了我正在处理的 KML 文件,没有发现任何可疑之处。这是程序应该处理的 KML 文件的简化结构:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<Document>
   <name>UK.kmz</name>
   <Style id="sh_blu-blank">
    <IconStyle>
        <scale>1.3</scale>
        <Icon>
            <href>http://maps.google.com/mapfiles/kml/paddle/blu-blank.png</href>
        </Icon>
        <hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/>
    </IconStyle>
    <ListStyle>
        <ItemIcon>
            <href>http://maps.google.com/mapfiles/kml/paddle/blu-blank-lv.png</href>
        </ItemIcon>
    </ListStyle>
  </Style>
    [other style tags...]
  <Folder>
    <name>UK</name>
    <Placemark>
        <name>1262 Crossness Pumping Station</name>
        <LookAt>
            <longitude>0.1329926667038817</longitude>
            <latitude>51.50303535104574</latitude>
            <altitude>0</altitude>
            <range>4246.539753518848</range>
            <tilt>0</tilt>
            <heading>-4.295161152207489</heading>
            <altitudeMode>relativeToGround</altitudeMode>
            <gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
        </LookAt>
        <styleUrl>#msn_blu-blank15000</styleUrl>
        <Point>
            <coordinates>0.1389579668507301,51.50888923518947,0</coordinates>
        </Point>
    </Placemark>
         [other placemark tags...]
  </Folder>
</Document>
</kml>

你知道为什么我不能访问“kml”的任何子元素吗?顺便说一下,Python 版本是 2.7。

4

1 回答 1

1

KML 文档位于http://earth.google.com/kml/2.2命名空间中,如下所示

<kml xmlns="http://earth.google.com/kml/2.2">

这意味着Document元素的名称实际上是{http://earth.google.com/kml/2.2}Document.

而不是这个:

document = kmlData.find('Document')

你需要这个:

document = kmlData.find('{http://earth.google.com/kml/2.2}Document')

但是,XML 文件存在问题。有一个元素叫做gx:altitudeMode。该gx位是命名空间前缀。需要声明这样的前缀,但缺少声明。

您只需用 替换即可解决该gx:问题gx。但正确的方法是添加命名空间声明。基于https://developers.google.com/kml/documentation/altitudemode,我认为它gxhttp://www.google.com/kml/ext/2.2命名空间相关联。因此,要使文档格式正确,根元素开始标记应为

<kml xmlns="http://earth.google.com/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">

现在可以解析文档:

In [1]: from xml.etree import ElementTree as ET

In [2]: kmlData = ET.parse("kml2.xml")

In [3]: document = kmlData.find('{http://earth.google.com/kml/2.2}Document')

In [4]: document
Out[4]: <Element '{http://earth.google.com/kml/2.2}Document' at 0x1895810>

In [5]:
于 2013-07-23T20:33:41.263 回答