如何更新 KML 以包含具有值的新元素

How to update a KML to include a new Element with a value

我的 KML 在元素地标下没有元素 "name"。因此,当使用 Google 地球打开 KML 时,树下的每个多边形旁边没有显示名称。

在下面的原始kml中,有2个Placemark。每个元素都有一个 Element simpleData name="ID"。与它们关联的2个值分别是FM2和FM3。

<?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>Test.kml</name>
    <open>1</open>
    <Schema name="test" id="S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
        <SimpleField type="string" name="ID"> <displayName>&lt;b&gt;ID&lt;/b&gt;</displayName>
    </SimpleField>
    <SimpleField type="string" name="cname"><displayName>&lt;b&gt;cname&lt;/b&gt;</displayName>
    </SimpleField>
    </Schema>
    <Style id="falseColor01">
        <BalloonStyle>
            <text><![CDATA[<table border="0"><tr> 
            <td>b>ID</b>/td>td>$[test/ID]</td></tr>
            <tr><td><b>cname</b></td><td>$[test/cname]</td></tr>
            </table>]]></text>
        </BalloonStyle>
        <LineStyle>
            <color>ffffff00</color>
            <width>3</width>
        </LineStyle>
        <PolyStyle>
            <color>ffffff00</color>
            <colorMode>random</colorMode>
            <fill>0</fill>
        </PolyStyle>
    </Style>
    <StyleMap id="falseColor0">
        <Pair>
            <key>normal</key>
            <styleUrl>#falseColor00</styleUrl>
        </Pair>
        <Pair>
            <key>highlight</key>
            <styleUrl>#falseColor01</styleUrl>
       </Pair>
    </StyleMap>
    <Style id="falseColor00">
      <BalloonStyle>   
      </BalloonStyle>
        <LineStyle>
            <color>ffffff00</color>
            <width>3</width>
        </LineStyle>
        <PolyStyle>
            <color>ffffff00</color>
            <colorMode>random</colorMode>
            <fill>0</fill>
        </PolyStyle>
    </Style>
    <Folder id="layer 0">
        <name>Test_1</name>
        <open>1</open>
        <Placemark>
            <styleUrl>#falseColor0</styleUrl>
            <ExtendedData>
                <SchemaData schemaUrl="#S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
                    <SimpleData name="ID">FM2</SimpleData>
                    <SimpleData name="cname">FM2</SimpleData>
                </SchemaData>
            </ExtendedData>
            <Polygon>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>150.889999,-32.17281600000001,0 
                        </coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
        <Placemark>
            <styleUrl>#falseColor0</styleUrl>
            <ExtendedData>
                <SchemaData schemaUrl="#S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
                    <SimpleData name="ID">FM3</SimpleData>
                    <SimpleData name="cname">FM3</SimpleData>
                </SchemaData>
            </ExtendedData>
            <Polygon>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>150.90104,-32.15662800000001,0
                        </coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
    </Folder>
</Document>
</kml>

在@DanielHaley 的帮助下,我能够读取元素值 FM2 和 FM3。

然后我尝试使用 lxml etree 教程在每个下添加一个元素 "name",值分别为 "FM2" 和 "FM3"。我没有运气。

这是我期望得到的:

    <Folder id="layer 0">
        <name>Test_1</name>
        <open>1</open>
        <Placemark>
            <name>FM2</name>
            <styleUrl>#falseColor0</styleUrl>
            <ExtendedData>
                <SchemaData schemaUrl="#S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
                    <SimpleData name="ID">FM2</SimpleData>
                    <SimpleData name="cname">FM2</SimpleData>
                </SchemaData>
            </ExtendedData>
            <Polygon>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>150.889999,-32.17281600000001,0 
                        </coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
        <Placemark>
            <name>FM3</name>
            <styleUrl>#falseColor0</styleUrl>
            <ExtendedData>
                <SchemaData schemaUrl="#S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
                    <SimpleData name="ID">FM3</SimpleData>
                    <SimpleData name="cname">FM3</SimpleData>
                </SchemaData>
            </ExtendedData>
            <Polygon>
                <outerBoundaryIs>
                    <LinearRing>
                        <coordinates>150.90104,-32.15662800000001,0
                        </coordinates>
                    </LinearRing>
                </outerBoundaryIs>
            </Polygon>
        </Placemark>
    </Folder>

谁能给我一个提示?

如果可以的话,能否请您稍微解释一下命名空间的概念?我查看了 Google 的教程,但解释并不完整。

如果要修改Placemark,请先修改select。

然后创建新的 name 元素并从 SimpleData 中提取值用作它的文本值。

最后将新元素插入Placemark

示例...

Python

from lxml import etree

ns = {"kml": "http://www.opengis.net/kml/2.2"}

# Using a parser to improve formatting of new "name" elements
# and, most importantly, to preserve CDATA sections.
parser = etree.XMLParser(remove_blank_text=True, strip_cdata=False)

tree = etree.parse("test.kml", parser=parser)

for placemark in tree.xpath("//kml:Placemark", namespaces=ns):
    # Create new "name" element in kml namespace ({http://www.opengis.net/kml/2.2}name).
    name_element = etree.Element(etree.QName(ns.get("kml"), "name"), nsmap=ns)

    # Set value of "name" element to value from SimpleData.
    name_element.text = placemark.xpath("kml:ExtendedData/kml:SchemaData/kml:SimpleData[@name='ID']/text()",
                                        namespaces=ns)[0]

    # Insert the new element into "placemark" as the first child.
    placemark.insert(0, name_element)

print(etree.tostring(tree, pretty_print=True).decode("UTF-8"))

印刷XML输出

<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>Test.kml</name>
    <open>1</open>
    <Schema name="test" id="S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
      <SimpleField type="string" name="ID">
        <displayName>&lt;b&gt;ID&lt;/b&gt;</displayName>
      </SimpleField>
      <SimpleField type="string" name="cname">
        <displayName>&lt;b&gt;cname&lt;/b&gt;</displayName>
      </SimpleField>
    </Schema>
    <Style id="falseColor01">
      <BalloonStyle>
        <text><![CDATA[<table border="0"><tr> 
            <td>b>ID</b>/td>td>$[test/ID]</td></tr>
            <tr><td><b>cname</b></td><td>$[test/cname]</td></tr>
            </table>]]></text>
      </BalloonStyle>
      <LineStyle>
        <color>ffffff00</color>
        <width>3</width>
      </LineStyle>
      <PolyStyle>
        <color>ffffff00</color>
        <colorMode>random</colorMode>
        <fill>0</fill>
      </PolyStyle>
    </Style>
    <StyleMap id="falseColor0">
      <Pair>
        <key>normal</key>
        <styleUrl>#falseColor00</styleUrl>
      </Pair>
      <Pair>
        <key>highlight</key>
        <styleUrl>#falseColor01</styleUrl>
      </Pair>
    </StyleMap>
    <Style id="falseColor00">
      <BalloonStyle>   
            </BalloonStyle>
      <LineStyle>
        <color>ffffff00</color>
        <width>3</width>
      </LineStyle>
      <PolyStyle>
        <color>ffffff00</color>
        <colorMode>random</colorMode>
        <fill>0</fill>
      </PolyStyle>
    </Style>
    <Folder id="layer 0">
      <name>Test_1</name>
      <open>1</open>
      <Placemark>
        <name>FM2</name>
        <styleUrl>#falseColor0</styleUrl>
        <ExtendedData>
          <SchemaData schemaUrl="#S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
            <SimpleData name="ID">FM2</SimpleData>
            <SimpleData name="cname">FM2</SimpleData>
          </SchemaData>
        </ExtendedData>
        <Polygon>
          <outerBoundaryIs>
            <LinearRing>
              <coordinates>150.889999,-32.17281600000001,0 
                            </coordinates>
            </LinearRing>
          </outerBoundaryIs>
        </Polygon>
      </Placemark>
      <Placemark>
        <name>FM3</name>
        <styleUrl>#falseColor0</styleUrl>
        <ExtendedData>
          <SchemaData schemaUrl="#S_test_SSSSSIIIDSDDDDDISSSDSSSDD">
            <SimpleData name="ID">FM3</SimpleData>
            <SimpleData name="cname">FM3</SimpleData>
          </SchemaData>
        </ExtendedData>
        <Polygon>
          <outerBoundaryIs>
            <LinearRing>
              <coordinates>150.90104,-32.15662800000001,0
                            </coordinates>
            </LinearRing>
          </outerBoundaryIs>
        </Polygon>
      </Placemark>
    </Folder>
  </Document>
</kml>

另外,see here 有关 XML 命名空间的更多信息。它的解释比我在这里做的更好。