【问题标题】:Remove KML 'name' tags using Python26使用 Python26 删除 KML“名称”标签
【发布时间】:2013-06-19 14:52:39
【问题描述】:

我的研究发现使用 XPath 和/或 xml ElementTree 应该可以工作,但是使用以下代码(我知道它需要一些工作 - 对 python 来说是新的),我无法产生我正在寻找的结果。

我希望将我的 kml 中超过单个字符的任何名称标签替换为空白字符串。我想保留元素树的结构,因为有重要的文件夹和子文件夹,因此由于未知缩进,逐行 string.replace 方法可能不起作用。

任何帮助将不胜感激,这就是我到目前为止所得到的。

import sys, string, os, lxml
import xml.etree.ElementTree as ET

kml_file = open(r'C:\temp\doc.kml', 'r')

tree = ET.parse(kml_file)
root = tree.getroot()
for name in root.findall('.//{http://www.opengis.net/kml/2.2}name'):
    if len(name.text) > 1:
        name.text = ""

kml_file.close()

示例 KML 代码:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
    <name>TempFile.kmz</name>
    <open>1</open>
    <StyleMap id="msn_ylw-pushpin">
        <Pair>
            <key>normal</key>
            <styleUrl>#sn_ylw-pushpin3</styleUrl>
        </Pair>
        <Pair>
            <key>highlight</key>
            <styleUrl>#sh_ylw-pushpin0</styleUrl>
        </Pair>
    </StyleMap>
    <Style id="sn_ylw-pushpin3">
        <IconStyle>
            <scale>1.1</scale>
            <Icon>
                <href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>
            </Icon>
            <hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
        </IconStyle>
    </Style>
    <Style id="sh_ylw-pushpin0">
        <IconStyle>
            <scale>1.3</scale>
            <Icon>
                <href>http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png</href>
            </Icon>
            <hotSpot x="20" y="2" xunits="pixels" yunits="pixels"/>
        </IconStyle>
    </Style>
    <Folder>
        <name>My Places</name>
        <open>1</open>
        <Style>
            <ListStyle>
                <listItemType>check</listItemType>
                <ItemIcon>
                    <state>open</state>
                    <href>C:/Documents and Settings/sfmeyer/Local Settings/Temp/wz5b57/files/mysavedplaces_open.png</href>
                </ItemIcon>
                <ItemIcon>
                    <state>closed</state>
                    <href>C:/Documents and Settings/sfmeyer/Local Settings/Temp/wz5b57/files/mysavedplaces_closed.png</href>
                </ItemIcon>
                <bgColor>00ffffff</bgColor>
                <maxSnippetLines>2</maxSnippetLines>
            </ListStyle>
        </Style>
        <Placemark>
            <name>NameRemove0</name>
            <LookAt>
                <longitude>-111.6385075333604</longitude>
                <latitude>33.89355748553</latitude>
                <altitude>0</altitude>
                <heading>-0.003511129776839782</heading>
                <tilt>18.73370091942461</tilt>
                <range>363.2207262112541</range>
                <gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>
            </LookAt>
            <styleUrl>#msn_ylw-pushpin</styleUrl>
            <Point>
                <gx:altitudeMode>clampToSeaFloor</gx:altitudeMode>
                <coordinates>-111.6380073829088,33.89304257965345,0</coordinates>
            </Point>
        </Placemark>
    </Folder>
</Document>
</kml>

错误:

File "C:\Program Files\Python26\ArcGIS10.0\lib\xml\etree\ElementTree.py", line 862, in parse
    tree.parse(source, parser)
  File "C:\Program Files\Python26\ArcGIS10.0\lib\xml\etree\ElementTree.py", line 587, in parse
    self._root = parser.close()
  File "C:\Program Files\Python26\ArcGIS10.0\lib\xml\etree\ElementTree.py", line 1254, in close
    self._parser.Parse("", 1) # end of data
ExpatError: unclosed CDATA section: line 286, column 77

【问题讨论】:

    标签: xml replace tags kml elementtree


    【解决方案1】:

    如果没有看到您的 KML 文件,我不能肯定这是您的问题,但很有可能“名称”可能不会出现在您的 KML 命名空间之外。查看此question 了解更多详细信息以及如何在lxml 中进行操作。

    在常规的 ElementTree 语法中,如果 doc.kml 的内容是 -

    <?xml version="1.0" encoding="UTF-8"?>
    <kml xmlns="http://www.opengis.net/kml/2.2">
      <Document>
        <name>KML Samples</name>
      </Document>
    </kml>
    

    你可以使用:

    import xml.etree.ElementTree as ET
    
    kml_file = open(r'C:\temp\doc.kml, 'r')
    
    tree = ET.parse(kml_file)
    root = tree.getroot()
    for name in root.findall('.//{http://www.opengis.net/kml/2.2}name'):
        if len(name.text) > 1:
            name.text = ""
    
    kml_file.close()
    

    【讨论】:

    • 非常感谢您的时间和样品。使用您提供的代码块,我返回一个错误。我已使用示例 KML 和错误消息编辑了我的原始评论。您对为什么会发生这种情况有任何想法吗?非常感谢。
    • @S.Meyer - 解析器对我来说也失败了,因为您发布的示例 KML 文件不是有效的 XML。试试this site。
    • 一旦我获得足够的声望就投票给你。非常感谢您的善意和慷慨的帮助。我最初只分享了代码的一部分,我编辑了我的源 KML 代码以反映一个有效的 XML 文档。但是,python脚本运行后,没有错误,KML名称保持不变,没有检测到变化?我还缺少其他东西吗?再次,非常感谢。
    • 好的,很简单。该脚本需要一些小的修改。请参阅下面的最终脚本。非常感谢@pauldom。
    • @S.Meyer - 您是否尝试修改文件本身中的名称? python 运算符只对缓冲区内的文件起作用,原始文件将保持不变。如果您想查看更改,您必须将它们写入新文件或用缓冲区的内容覆盖旧文件
    【解决方案2】:

    从原始脚本中,我添加了一个带有输出名称的变量,以及一个用于在末尾写入新文件的函数。 我原始帖子的“错误:”部分是由于 KML 文档中的格式无效,@pauldom 指出这是因为我只分享了整个文档的一部分。

    import sys, string, os, lxml
    import xml.etree.ElementTree as ET
    
    kml_file = open(r'C:\temp\doc.kml', 'r+')
    kml_file2 = (r'C:\temp\doc2.kml')
    
    tree = ET.parse(kml_file)
    root = tree.getroot()
    for name in root.findall('.//{http://www.opengis.net/kml/2.2}name'):
        if len(name.text) > 1:
            name.text = "n/a"
            tree.write(kml_file2)                
    kml_file.close()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-02
      • 1970-01-01
      • 2014-07-12
      • 2018-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多