我无法弄清楚如何替换已经具有命名空间(除pytype之外)的lxml StringElement(在本例中为styleUrl)的内容。我最终注入了元素级命名空间。这是一个非常精简和简化的版本,只试图重命名一个StyleMap来说明问题:
#!/usr/bin/env python
from __future__ import print_function
import sys
from pykml import parser as kmlparser
from lxml import objectify
frm = "lineStyle30218901714341461519022"
to = "s1"
b4_et = kmlparser.parse('b4.kml')
b4_root = b4_et
el = b4_root.xpath('//*[@id="%s"]' % frm)[0]
el.attrib['id'] = to
el = b4_root.xpath('//*[text()="#%s"]' % frm)[0]
el.xpath('./..')[0].styleUrl = '#'+to
objectify.deannotate(b4_root, xsi_nil=True)
b4_et.write(sys.stdout, pretty_print=True)
测试数据:
<?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>Wasatch Trails</name>
<open>1</open>
<Style id="lineStyle30218901714341461519049">
<LineStyle><color>ff0080ff</color><width>4</width></LineStyle>
</Style>
<Style id="lineStyle30218901714341461519027">
<LineStyle><color>ff0080ff</color><width>4</width></LineStyle>
</Style>
<StyleMap id="lineStyle30218901714341461519022">
<Pair><key>normal</key><styleUrl>#lineStyle30218901714341461519049</styleUrl></Pair>
<Pair><key>highlight</key><styleUrl>#lineStyle30218901714341461519027</styleUrl></Pair>
</StyleMap>
<Placemark>
<name>Trail</name>
<styleUrl>#lineStyle30218901714341461519022</styleUrl>
<LineString>
<tessellate>1</tessellate>
<coordinates>
-111.6472637672589,40.4810633294269,0 -111.650415221546,40.48116138407261,0 -111.6504410181637,40.48118694372887,0
</coordinates>
</LineString>
</Placemark>
</Document>
</kml>
我唯一无法解决的问题是lxml将 xmlns:py="http://codespeak.net/lxml/objectify/pytype"
属性放入新创建的styleUrl元素中。我猜这是由于文件具有kml / 2.2的默认命名空间。我不知道怎么告诉它新的styleUrl应该是kml而不是pytype。
...
<styleUrl xmlns:py="http://codespeak.net/lxml/objectify/pytype">#s1</styleUrl>
...
答案 0 :(得分:1)
替换以下内容:
el.xpath('./..')[0].styleUrl = '#'+to
使用:
el.xpath('./..')[0].styleUrl = objectify.StringElement('#' + to)
会给你你想要的东西。但我不确定这是否是最佳方式。
顺便说一句,您可以使用set(key, value)
方法设置属性值:
el.set('id', to) # isntead of el.attrib['id'] = to