如何更新 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><b>ID</b></displayName>
</SimpleField>
<SimpleField type="string" name="cname"><displayName><b>cname</b></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><b>ID</b></displayName>
</SimpleField>
<SimpleField type="string" name="cname">
<displayName><b>cname</b></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 命名空间的更多信息。它的解释比我在这里做的更好。
我的 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><b>ID</b></displayName>
</SimpleField>
<SimpleField type="string" name="cname"><displayName><b>cname</b></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><b>ID</b></displayName>
</SimpleField>
<SimpleField type="string" name="cname">
<displayName><b>cname</b></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 命名空间的更多信息。它的解释比我在这里做的更好。