使用 Pykml 解析 XML
Parsing XML with Pykml
我从 QGIS
获得了以下 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" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<name>stationpivot.kml</name>
<StyleMap id="default0">
<Pair>
<key>normal</key>
<styleUrl>#default</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#hl</styleUrl>
</Pair>
</StyleMap>
<Style id="hl">
<IconStyle>
<scale>0.7</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/shapes/placemark_circle_highlight.png</href>
</Icon>
</IconStyle>
<LabelStyle>
<scale>0.7</scale>
</LabelStyle>
</Style>
<Style id="default">
<IconStyle>
<scale>0.7</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/shapes/placemark_circle.png</href>
</Icon>
</IconStyle>
<LabelStyle>
<scale>0.7</scale>
</LabelStyle>
</Style>
<Folder>
<name>stationXML</name>
<open>1</open>
<Placemark>
<name>2</name>
<Snippet maxLines="0"></Snippet>
<description><![CDATA[<html><body><table border="1">
<tr><th>Field Name</th><th>Field Value</th></tr>
<tr><td>Latitude</td><td>26.719803</td></tr>
<tr><td>Longitude</td><td>40.861876</td></tr>
<tr><td>Name</td><td>REALNAME2</td></tr>
<tr><td>Vegetation</td><td>v_type2</td></tr>
<tr><td>Description</td><td>text text text text</td></tr>
<tr><td>Time Description</td><td>time time time </td></tr>
</table></body></html>]]></description>
<styleUrl>#default0</styleUrl>
<Point>
<gx:drawOrder>1</gx:drawOrder>
<coordinates>40.861876,26.71980299999999,0</coordinates>
</Point>
</Placemark>
<Placemark>
<name>3</name>
<Snippet maxLines="0"></Snippet>
<description><![CDATA[<html><body><table border="1">
<tr><th>Field Name</th><th>Field Value</th></tr>
<tr><td>Latitude</td><td>46.745151</td></tr>
<tr><td>Longitude</td><td>10.788845</td></tr>
<tr><td>Name</td><td>REALNAME3</td></tr>
<tr><td>Vegetation</td><td>v_type3</td></tr>
<tr><td>Description</td><td>text text text text</td></tr>
<tr><td>Time Description</td><td>time time time</td></tr>
</table></body></html>]]></description>
<styleUrl>#default0</styleUrl>
<Point>
<gx:drawOrder>1</gx:drawOrder>
<coordinates>40.788845,26.74515100000001,0</coordinates>
</Point>
</Placemark>
</Folder>
</Document>
</kml>
我想递归地替换
中的值“2”
<name>2</name>
<name>3</name>
字段使用“描述”字段中包含的信息 REALNAME2
为了拥有
<name>REALNAME2</name>
<name>REALNAME3</name>
分别作为我的 kml 中的最终输出
有什么建议吗?
我推荐你使用element tree API together with XPath。它非常易于使用且非常强大。它将使您能够做您想做的事:
import xml.etree.ElementTree as ET
root = ET.fromstring(<your KML as string>)
name_list = root.findall(".//Placemark/name")
for name in name_list:
name.text = "Some new text"
使用更新地标名称并创建新 KML 文件的 pykml 模块的完整代码。
from pykml import parser
import re
import lxml.etree as et
with open('test.kml', 'r') as f:
doc = parser.parse(f)
for pm in doc.getroot().Document.Folder.Placemark:
# look for realname in description in markup
# <tr><td>Name</td><td>*REALNAME2*</td></tr>
r = re.search(r'<tr><td>Name</td><td>([^<]+)', pm.description.text)
if r:
pm.name = r.group(1)
# output new KML file
with open('out.kml', 'wb') as output:
output.write(et.tostring(doc, pretty_print=True))
我从 QGIS
获得了以下 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" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<Document>
<name>stationpivot.kml</name>
<StyleMap id="default0">
<Pair>
<key>normal</key>
<styleUrl>#default</styleUrl>
</Pair>
<Pair>
<key>highlight</key>
<styleUrl>#hl</styleUrl>
</Pair>
</StyleMap>
<Style id="hl">
<IconStyle>
<scale>0.7</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/shapes/placemark_circle_highlight.png</href>
</Icon>
</IconStyle>
<LabelStyle>
<scale>0.7</scale>
</LabelStyle>
</Style>
<Style id="default">
<IconStyle>
<scale>0.7</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/shapes/placemark_circle.png</href>
</Icon>
</IconStyle>
<LabelStyle>
<scale>0.7</scale>
</LabelStyle>
</Style>
<Folder>
<name>stationXML</name>
<open>1</open>
<Placemark>
<name>2</name>
<Snippet maxLines="0"></Snippet>
<description><![CDATA[<html><body><table border="1">
<tr><th>Field Name</th><th>Field Value</th></tr>
<tr><td>Latitude</td><td>26.719803</td></tr>
<tr><td>Longitude</td><td>40.861876</td></tr>
<tr><td>Name</td><td>REALNAME2</td></tr>
<tr><td>Vegetation</td><td>v_type2</td></tr>
<tr><td>Description</td><td>text text text text</td></tr>
<tr><td>Time Description</td><td>time time time </td></tr>
</table></body></html>]]></description>
<styleUrl>#default0</styleUrl>
<Point>
<gx:drawOrder>1</gx:drawOrder>
<coordinates>40.861876,26.71980299999999,0</coordinates>
</Point>
</Placemark>
<Placemark>
<name>3</name>
<Snippet maxLines="0"></Snippet>
<description><![CDATA[<html><body><table border="1">
<tr><th>Field Name</th><th>Field Value</th></tr>
<tr><td>Latitude</td><td>46.745151</td></tr>
<tr><td>Longitude</td><td>10.788845</td></tr>
<tr><td>Name</td><td>REALNAME3</td></tr>
<tr><td>Vegetation</td><td>v_type3</td></tr>
<tr><td>Description</td><td>text text text text</td></tr>
<tr><td>Time Description</td><td>time time time</td></tr>
</table></body></html>]]></description>
<styleUrl>#default0</styleUrl>
<Point>
<gx:drawOrder>1</gx:drawOrder>
<coordinates>40.788845,26.74515100000001,0</coordinates>
</Point>
</Placemark>
</Folder>
</Document>
</kml>
我想递归地替换
中的值“2” <name>2</name>
<name>3</name>
字段使用“描述”字段中包含的信息 REALNAME2 为了拥有
<name>REALNAME2</name>
<name>REALNAME3</name>
分别作为我的 kml 中的最终输出
有什么建议吗?
我推荐你使用element tree API together with XPath。它非常易于使用且非常强大。它将使您能够做您想做的事:
import xml.etree.ElementTree as ET
root = ET.fromstring(<your KML as string>)
name_list = root.findall(".//Placemark/name")
for name in name_list:
name.text = "Some new text"
使用更新地标名称并创建新 KML 文件的 pykml 模块的完整代码。
from pykml import parser
import re
import lxml.etree as et
with open('test.kml', 'r') as f:
doc = parser.parse(f)
for pm in doc.getroot().Document.Folder.Placemark:
# look for realname in description in markup
# <tr><td>Name</td><td>*REALNAME2*</td></tr>
r = re.search(r'<tr><td>Name</td><td>([^<]+)', pm.description.text)
if r:
pm.name = r.group(1)
# output new KML file
with open('out.kml', 'wb') as output:
output.write(et.tostring(doc, pretty_print=True))