I'm trying to:
- read a KML file
- remove the Placemark element if name = 'ZONE'
- write a new KML file without the element
This is my code:
from pykml import parser
kml_file_path = '../Source/Lombardia.kml'
removeList = list()
with open(kml_file_path) as f:
folder = parser.parse(f).getroot().Document.Folder
for pm in folder.Placemark:
if pm.name == 'ZONE':
removeList.append(pm)
print pm.name
for tag in removeList:
parent = tag.getparent()
parent.remove(tag)
#Write the new file
#I cannot reach the solution help me
and this is the KML:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.2">
<Document>
<name>Lombardia</name>
<Style>
...
</Style>
<Folder>
<Placemark>
<name>ZOGNO</name>
<styleUrl>#FEATURES_LABELS</styleUrl>
<Point>
<coordinates>9.680530595139061,45.7941656233647,0</coordinates>
</Point>
</Placemark>
<Placemark>
<name>ZONE</name>
<styleUrl>#FEATURES_LABELS</styleUrl>
<Point>
<coordinates>10.1315885854064,45.7592449779275,0</coordinates>
</Point>
</Placemark>
</Folder>
</Document>
</kml>
The problem is that when I write the new KML file this still has the element I want to delete. In fact, with I want to delete the element that contains name = ZONE. What i'm doing wrong? Thank you.
--- Final Code This is the working code thanks to @Dawid Ferenczy:
from lxml import etree
import pykml
from pykml import parser
kml_file_path = '../Source/Lombardia.kml'
# parse the input file into an object tree
with open(kml_file_path) as f:
tree = parser.parse(f)
# get a reference to the "Document.Folder" node
folder = tree.getroot().Document.Folder
# iterate through all "Document.Folder.Placemark" nodes and find and remove all nodes
# which contain child node "name" with content "ZONE"
for pm in folder.Placemark:
if pm.name == 'ZOGNO':
parent = pm.getparent()
parent.remove(pm)
# convert the object tree into a string and write it into an output file
with open('output.kml', 'w') as output:
output.write(etree.tostring(folder, pretty_print=True))
You have the following issues in your code:
folder = parser.parse(f).getroot().Document.Folder
) but you want to write it back into a file so you need to store itremoveList
when you can delete elements directly in the first loopTry the following code:
from lxml import etree
from pykml import parser
kml_file_path = './input.kml'
# parse the input file into an object tree
with open(kml_file_path) as f:
tree = parser.parse(f)
# get a reference to the "Document.Folder" node
folder = tree.getroot().Document.Folder
# iterate through all "Document.Folder.Placemark" nodes and find and remove all nodes
# which contain child node "name" with content "ZONE"
for pm in folder.Placemark:
if pm.name == 'ZONE':
parent = pm.getparent()
parent.remove(pm)
# convert the object tree into a string and write it into an output file
with open('output.kml', 'w') as output:
output.write(etree.tostring(tree, pretty_print=True))
It's very simple:
tree