使用 lxml 编辑 KML 的内容
Editing the content of a KML using lxml
我有一个简单的 KML 文件,我想使用 etree.XMLParser 修改它。
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document id="root_doc">
<Schema name="test" id="test">
<SimpleField name="id" type="string"/>
<SimpleField name="LAT" type="float"/>
<SimpleField name="LONG" type="float"/>
</Schema>
<Folder>
<name>test</name>
<Placemark>
<Style>
<LineStyle><color>ff0000ff</color></LineStyle>
<PolyStyle><fill>0</fill></PolyStyle>
</Style>
<ExtendedData>
<SchemaData schemaUrl="#test">
<SimpleData name="id">ABC</SimpleData>
<SimpleData name="LAT">-35.06111</SimpleData>
<SimpleData name="LONG">138.58389</SimpleData>
</SchemaData>
</ExtendedData>
<Polygon>
<outerBoundaryIs>
<LinearRing>
<coordinates>138.58389,-35.06111 138.585208,-35.059241
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Folder>
</Document>
</kml>
首先,如何将 document 下的架构 ID 和 Placemark 下的 schemaUrl 从 'test' 更改为 'test_1'?我试过了,但没用:
ns = {"kml": "http://www.opengis.net/kml/2.2"}
schema_element = placemark.xpath("kml:ExtendedData/kml:SchemaData[@schemaUrl]", namespaces=ns)[0]
schema_element.text = 'test_1'
其次,我想为文档插入一个新样式。我正在考虑创建一个字符串和一个 string_element。在文档下插入 string_element:
style_element = etree.Element(etree.QName(ns.get("kml"), "style"), nsmap=ns)
style_element.text = style_str
document_element = tree.xpath("//kml:Document", namespaces=ns)
document_element.insert(1, style_str)
这是我想要的最终输出:
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document id="root_doc">
<Schema name="test" id="test_1">
<SimpleField name="id" type="string"/>
<SimpleField name="LAT" type="float"/>
<SimpleField name="LONG" type="float"/>
</Schema>
<Style id="falseColor">
<BalloonStyle>
<text><![CDATA[<table border="0">
<tr><td><b>ID</b></td><td>$[test/id]</td></tr>
<tr><td><b>LAT</b></td><td>$[test/LAT]</td></tr>
<tr><td><b>LON</b></td><td>$[test/LONG]</td></tr>
</table>]]>
</text>
</BalloonStyle>
<PolyStyle>
<colorMode>random</colorMode>
</PolyStyle>
</Style>
<Folder>
<name>test</name>
<Placemark>
<styleUrl>#falseColor</styleUrl>
<ExtendedData>
<SchemaData schemaUrl="#test_1">
<SimpleData name="id">ABC</SimpleData>
<SimpleData name="LAT">-35.06111</SimpleData>
<SimpleData name="LONG">138.58389</SimpleData>
</SchemaData>
</ExtendedData>
<Polygon>
<outerBoundaryIs>
<LinearRing>
<coordinates>138.58389,-35.06111 138.585208,-35.059241
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Folder>
</Document>
</kml>
有人可以帮忙吗?
谢谢
第 1 部分:schemaUrl
是一个属性。找到属性所属的元素并设置一个新值:
schemadata_element = tree.xpath("//kml:SchemaData", namespaces=ns)[0]
schemadata_element.set("schemaUrl", "#test_1")
Schema
元素的 id
属性以相同的方式更新。
第 2 部分:添加新样式有点棘手,但并不难。将 Style
元素创建为字符串,通过 fromstring()
将其解析为 Element
对象(确保使用 strip_cdata=False
解析器选项保留 CDATA 部分),以及然后在适当的位置插入元素。
完成这两个部分的完整代码(并删除现有的 Style
元素):
from lxml import etree
ns = {"kml": "http://www.opengis.net/kml/2.2"}
parser = etree.XMLParser(remove_blank_text=True, strip_cdata=False)
tree = etree.parse("your_kml_file.xml", parser)
schema_element = tree.xpath("//kml:Schema", namespaces=ns)[0]
schema_element.set("id", "test_1")
schemadata_element = tree.xpath("//kml:SchemaData", namespaces=ns)[0]
schemadata_element.set("schemaUrl", "#test_1")
# Remove existing "Style" element and add "styleUrl" element
old_style_element = tree.xpath("//kml:Style", namespaces=ns)[0]
placemark = old_style_element.getparent()
placemark.remove(old_style_element)
styleurl_element = etree.Element(etree.QName(ns["kml"], "styleUrl"))
styleurl_element.text = "#falseColor"
placemark.insert(0, styleurl_element)
# Add new "Style" element
style_str = """
<Style id="falseColor" xmlns="http://www.opengis.net/kml/2.2">
<BalloonStyle>
<text><![CDATA[<table border="0">
<tr><td><b>ID</b></td><td>$[test/id]</td></tr>
<tr><td><b>LAT</b></td><td>$[test/LAT]</td></tr>
<tr><td><b>LON</b></td><td>$[test/LONG]</td></tr>
</table>]]>
</text>
</BalloonStyle>
<PolyStyle>
<colorMode>random</colorMode>
</PolyStyle>
</Style>"""
style_element = etree.fromstring(style_str, parser)
document_element = tree.xpath("//kml:Document", namespaces=ns)[0]
document_element.insert(1, style_element)
我有一个简单的 KML 文件,我想使用 etree.XMLParser 修改它。
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document id="root_doc">
<Schema name="test" id="test">
<SimpleField name="id" type="string"/>
<SimpleField name="LAT" type="float"/>
<SimpleField name="LONG" type="float"/>
</Schema>
<Folder>
<name>test</name>
<Placemark>
<Style>
<LineStyle><color>ff0000ff</color></LineStyle>
<PolyStyle><fill>0</fill></PolyStyle>
</Style>
<ExtendedData>
<SchemaData schemaUrl="#test">
<SimpleData name="id">ABC</SimpleData>
<SimpleData name="LAT">-35.06111</SimpleData>
<SimpleData name="LONG">138.58389</SimpleData>
</SchemaData>
</ExtendedData>
<Polygon>
<outerBoundaryIs>
<LinearRing>
<coordinates>138.58389,-35.06111 138.585208,-35.059241
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Folder>
</Document>
</kml>
首先,如何将 document 下的架构 ID 和 Placemark 下的 schemaUrl 从 'test' 更改为 'test_1'?我试过了,但没用:
ns = {"kml": "http://www.opengis.net/kml/2.2"}
schema_element = placemark.xpath("kml:ExtendedData/kml:SchemaData[@schemaUrl]", namespaces=ns)[0]
schema_element.text = 'test_1'
其次,我想为文档插入一个新样式。我正在考虑创建一个字符串和一个 string_element。在文档下插入 string_element:
style_element = etree.Element(etree.QName(ns.get("kml"), "style"), nsmap=ns)
style_element.text = style_str
document_element = tree.xpath("//kml:Document", namespaces=ns)
document_element.insert(1, style_str)
这是我想要的最终输出:
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document id="root_doc">
<Schema name="test" id="test_1">
<SimpleField name="id" type="string"/>
<SimpleField name="LAT" type="float"/>
<SimpleField name="LONG" type="float"/>
</Schema>
<Style id="falseColor">
<BalloonStyle>
<text><![CDATA[<table border="0">
<tr><td><b>ID</b></td><td>$[test/id]</td></tr>
<tr><td><b>LAT</b></td><td>$[test/LAT]</td></tr>
<tr><td><b>LON</b></td><td>$[test/LONG]</td></tr>
</table>]]>
</text>
</BalloonStyle>
<PolyStyle>
<colorMode>random</colorMode>
</PolyStyle>
</Style>
<Folder>
<name>test</name>
<Placemark>
<styleUrl>#falseColor</styleUrl>
<ExtendedData>
<SchemaData schemaUrl="#test_1">
<SimpleData name="id">ABC</SimpleData>
<SimpleData name="LAT">-35.06111</SimpleData>
<SimpleData name="LONG">138.58389</SimpleData>
</SchemaData>
</ExtendedData>
<Polygon>
<outerBoundaryIs>
<LinearRing>
<coordinates>138.58389,-35.06111 138.585208,-35.059241
</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Folder>
</Document>
</kml>
有人可以帮忙吗?
谢谢
第 1 部分:schemaUrl
是一个属性。找到属性所属的元素并设置一个新值:
schemadata_element = tree.xpath("//kml:SchemaData", namespaces=ns)[0]
schemadata_element.set("schemaUrl", "#test_1")
Schema
元素的 id
属性以相同的方式更新。
第 2 部分:添加新样式有点棘手,但并不难。将 Style
元素创建为字符串,通过 fromstring()
将其解析为 Element
对象(确保使用 strip_cdata=False
解析器选项保留 CDATA 部分),以及然后在适当的位置插入元素。
完成这两个部分的完整代码(并删除现有的 Style
元素):
from lxml import etree
ns = {"kml": "http://www.opengis.net/kml/2.2"}
parser = etree.XMLParser(remove_blank_text=True, strip_cdata=False)
tree = etree.parse("your_kml_file.xml", parser)
schema_element = tree.xpath("//kml:Schema", namespaces=ns)[0]
schema_element.set("id", "test_1")
schemadata_element = tree.xpath("//kml:SchemaData", namespaces=ns)[0]
schemadata_element.set("schemaUrl", "#test_1")
# Remove existing "Style" element and add "styleUrl" element
old_style_element = tree.xpath("//kml:Style", namespaces=ns)[0]
placemark = old_style_element.getparent()
placemark.remove(old_style_element)
styleurl_element = etree.Element(etree.QName(ns["kml"], "styleUrl"))
styleurl_element.text = "#falseColor"
placemark.insert(0, styleurl_element)
# Add new "Style" element
style_str = """
<Style id="falseColor" xmlns="http://www.opengis.net/kml/2.2">
<BalloonStyle>
<text><![CDATA[<table border="0">
<tr><td><b>ID</b></td><td>$[test/id]</td></tr>
<tr><td><b>LAT</b></td><td>$[test/LAT]</td></tr>
<tr><td><b>LON</b></td><td>$[test/LONG]</td></tr>
</table>]]>
</text>
</BalloonStyle>
<PolyStyle>
<colorMode>random</colorMode>
</PolyStyle>
</Style>"""
style_element = etree.fromstring(style_str, parser)
document_element = tree.xpath("//kml:Document", namespaces=ns)[0]
document_element.insert(1, style_element)