我不知道如何替换已经有命名空间(除 pytype 之外)的 lxml StringElement (本例中为 styleUrl)的内容。我最终得到了一个元素级命名空间注入(inject)。这是一个经过精炼和简化的版本,仅尝试重命名一个 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>
...
最佳答案
替换以下内容:
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
关于python - 通过启动命名空间 war 来替换 lxml StringElement 的内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24956087/