使用lxml编辑KML的内容

问题描述 投票:0回答:1

我有一个简单的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>

[首先,如何将文档和地标下的schemaUrl下的模式ID从'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>

有人可以帮忙吗?

谢谢

python lxml kml
1个回答
0
投票

第1部分:schemaUrl是属性。找到属性所属的元素并设置一个新值:

schemadata_element = tree.xpath("//kml:SchemaData", namespaces=ns)[0]
schemadata_element.set("schemaUrl", "#test_1")

id元素上的Schema属性以相同的方式更新。


第2部分:添加新样式有点棘手,但并不是很难。将Style元素创建为字符串,通过Element将其解析为fromstring()对象(确保使用strip_cdata=False parser选项保留CDATA节),然后将元素插入适当的位置。

同时完成这两个部分的代码:

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")

style_str = f"""
<Style id="falseColor" xmlns="{ns['kml']}">
    <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)
© www.soinside.com 2019 - 2024. All rights reserved.