#python #xml #automation #gis #kml
#python #xml #автоматизация #гис #kml
Вопрос:
Я сгенерировал файл KML, используя библиотеку SimpleKML на Python и следующий скрипт, вывод которого также показан ниже:
import simplekml
kml = simplekml.Kml()
ground = kml.newgroundoverlay(name='Aerial Extent')
ground.icon.href = 'C:\Users\mdl518\Desktop\aerial_image.png'
ground.latlonbox.north = 46.55537
ground.latlonbox.south = 46.53134
ground.latlonbox.east = 48.60005
ground.latlonbox.west = 48.57678
ground.latlonbox.rotation = 0.090320
kml.save(".//aerial_extent.kml")
Вывод KML:
<?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">
<Document id="1">
<GroundOverlay id="2">
<name>Aerial Extent</name>
<Icon id="3">
<href>C:\Users\mdl518\Desktop\aerial_image.png</href>
</Icon>
<LatLonBox>
<north>46.55537</north>
<south>46.53134</south>
<east>48.60005</east>
<west>48.57678</west>
<rotation>0.090320</rotation>
</LatLonBox>
</GroundOverlay>
</Document>
Тем не менее, я пытаюсь удалить тег «Document» из этого KML, поскольку он является элементом по умолчанию, созданным с помощью SimpleKML, сохраняя при этом дочерние элементы (например, GroundOverlay). Кроме того, есть ли способ удалить атрибуты «id», связанные с определенными элементами (например, для GroundOverlay, элементов Icon)? Я изучаю использование ElementTree / lxml, чтобы включить это, но они, похоже, более специфичны для файлов XML, в отличие от KML. Вот что я пытаюсь использовать для изменения KML, но он не может удалить элемент Document:
from lxml import etree
tree = etree.fromstring(open("C:\Users\mdl518\Desktop\aerial_extent.kml").read())
for item in tree.xpath("//Document[@id='1']"):
item.getparent().remove(item)
print(etree.tostring(tree, pretty_print=True))
Вот конечный желаемый выходной XML:
<?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">
<GroundOverlay>
<name>Aerial Extent</name>
<Icon>
<href>C:\Users\mdl518\Desktop\aerial_image.png</href>
</Icon>
<LatLonBox>
<north>46.55537</north>
<south>46.53134</south>
<east>48.60005</east>
<west>48.57678</west>
<rotation>0.090320</rotation>
</LatLonBox>
</GroundOverlay>
</kml>
Любые идеи приветствуются!
Комментарии:
1. Файлы KML также являются XML, поэтому lxml — прекрасный способ манипулировать ими. Будет ли он по-прежнему действительным KML после ваших изменений, это, конечно, зависит от вас 🙂
2. @Thomas — Я понимаю, что KML-файлы по сути являются XML-файлами, но я просто наблюдал за тем, что казалось чувствительным к расширениям файлов, используя библиотеки lxml / ElementTree. Я обновил свой пост, показывающий скрипт, который я пытаюсь использовать для удаления тега Document, любая помощь приветствуется!
Ответ №1:
Вы сталкиваетесь с ужасными пространствами имен…
Попробуйте использовать что-то вроде этого:
ns = {'kml': 'http://www.opengis.net/kml/2.2'}
for item in tree.xpath("//kml:Document[@id='1']",namespaces=ns):
item.getparent().remove(item)
Редактировать:
Чтобы удалить только родительский элемент и сохранить все его потомки, попробуйте выполнить следующие действия:
retain = doc.xpath("//kml:Document[@id='1']/kml:GroundOverlay",namespaces=ns)[0]
for item in doc.xpath("//kml:Document[@id='1']",namespaces=ns):
anchor = item.getparent()
anchor.remove(item)
anchor.insert(1,retain)
print(etree.tostring(doc, pretty_print=True).decode())
Это должно дать вам желаемый результат.
Комментарии:
1. Это помогает указать мне правильное направление, но выполнение этого скрипта удаляет все дочерние элементы ниже элемента «Document». Я буду продолжать подключаться к этому, поскольку для получения правильного решения должно быть всего несколько настроек, еще раз спасибо!
2. @mdl518 Ну, это то, что вы сказали в своем вопросе — вы хотели удалить
<Document>
элемент; это включает в себя все, что внутри него. Если это не то, что вам нужно, вам, вероятно, следует опубликовать другой вопрос с другим xml и желаемым результатом.3. Приношу свои извинения за любую двусмысленность, но да, идея состоит в том, чтобы удалить элемент Document, сохранив дочерние элементы (например, GroundOverlay). Теперь это отражено в обновленном сообщении.
4. @mdl518 Теперь я понимаю, но вам, вероятно, следует снова отредактировать свой вопрос и показать точный ожидаемый результат.
5. Спасибо за ваш полезный отзыв, теперь это добавлено к исходному сообщению … очень ценится!