lxml - 如何根据特定属性将元素移动到文件夹中

lxml - how to move elements into a folder based on a certain attribute

我有一个包含大量地标和 2 个文件夹的 KML。 如何使用 etree 定位每个地标并将其移动到相应的文件夹中。 例如,代码应该查找元素“SimpleData name='id'”并选择 'Region 1',然后将整个 Plaemark 移动到文件夹 Area 1.

之前:

<Folder>
    <name>Cluster</name>
    <Folder>Area 1</Folder>
    <Folder>Area 2</Folder>
    <Placemark>
        <styleUrl>#falseColor9</styleUrl>
        <name>Customer 1</name>
        <ExtendedData>
            <SimpleData name="id">Region 1</SimpleData>
        </ExtendedData>
    </Placemark>
    <Placemark>
        <styleUrl>#falseColor8</styleUrl>
        <name>Customer 1</name>
        <ExtendedData>
            <SimpleData name="id">Region 2</SimpleData>
        </ExtendedData>
    </Placemark>    
</Folder>

之后:

<Folder>
    <name>Cluster</name>
    <Folder>Area 1</Folder>
        <Placemark>
            <name>Customer 1</name>
            <styleUrl>#falseColor9</styleUrl>           
            <ExtendedData>
                <SimpleData name="id">Region 1</SimpleData>
            </ExtendedData>
        </Placemark>
    <Folder>Area 2</Folder>
        <Placemark>
            <styleUrl>#falseColor8</styleUrl>
            <name>Customer 1</name>
            <ExtendedData>
                <SimpleData name="id">Region 2</SimpleData>
            </ExtendedData>
        </Placemark>    
</Folder>

如有任何帮助,我们将不胜感激。

使用 lxml,可以这样做:

from lxml import etree
marks = """[your xml above]"""
doc = etree.XML(marks.encode())
for region in doc.xpath('//SimpleData'):
    target = region.text.split(' ')[1].strip()
    dests = doc.xpath('//Folder//Folder')
    for dest in dests:
        if target in dest.text:
            move =region.xpath('ancestor::Placemark')[0]
            dest.addnext((move))
print(etree.tostring(doc).decode())

输出:

<Folder>
   <name>Cluster</name>
   <Folder>Area 1</Folder>
    <Placemark>
      <styleUrl>#falseColor9</styleUrl>
      <name>Customer 1</name>
      <ExtendedData>
         <SimpleData name="id">Region 1</SimpleData>
      </ExtendedData>
   </Placemark>
   
   <Folder>Area 2</Folder>
   <Placemark>
      <styleUrl>#falseColor8</styleUrl>
      <name>Customer 1</name>
      <ExtendedData>
         <SimpleData name="id">Region 2</SimpleData>
      </ExtendedData>
   </Placemark>
   </Folder>