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>
我有一个包含大量地标和 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>