如何使用相同的命名空间用字符串片段替换某个元素?
<!-- language: python -->
from lxml import etree
replacestring = '''<AP_PTO gml:id="DEAL123456789abc">
<new>This Element is new!</new>
</AP_PTO>'''
file = etree.parse("nasfile.xml")
root = file.getroot()
nsmap = root.nsmap.copy()
nsmap['adv'] = nsmap.pop(None)
nodes = root.xpath(".//adv:geaenderteObjekte/wfs:Transaction", namespaces=nsmap)
# Iterate object elements
for t in nodes[0]:
for obj in t:
oart = str(etree.QName(objekt.tag).localname)
if oart == 'Filter':
pass
else:
objid = (obj.xpath('@gml:id', namespaces=nsmap))[0][:16]
if objid == 'DEAL123456789abc':
t.replace(obj, etree.fromstring(replacestring))
#nodes[0].remove(t)
我从输入文件中获取名称空间为nsmap:
{'adv': 'http://www.adv-online.de/namespaces/adv/gid/6.0',
'asdkom': 'http://www.lverma.nrw.de/namespaces/kom-ok/1.1',
'fc': 'http://www.adv-online.de/namespaces/adv/gid/fc/6.0',
'gco': 'http://www.isotc211.org/2005/gco',
'gmd': 'http://www.isotc211.org/2005/gmd',
'gml': 'http://www.opengis.net/gml/3.2',
'gsr': 'http://www.isotc211.org/2005/gsr',
'gss': 'http://www.isotc211.org/2005/gss',
'gts': 'http://www.isotc211.org/2005/gts',
'ogc': 'http://www.adv-online.de/namespaces/adv/gid/ogc',
'wfs': 'http://www.adv-online.de/namespaces/adv/gid/wfs',
'wfsext': 'http://www.adv-online.de/namespaces/adv/gid/wfsext',
'xlink': 'http://www.w3.org/1999/xlink',
'xs': 'http://www.w3.org/2001/XMLSchema',
'xsi': 'http://www.w3.org/2001/XMLSchema-instance'}
如果我从replacestring中删除gml:Prefix,则循环按预期工作。该字符串用给定的ID替换前一个元素。但是我用前缀得到了: XMLSyntaxError:未定义AP_PTO上id的名称空间前缀gml,第2行,第34列
如何告诉lxml使用源文件中nsmap中定义的命名空间?
答案 0 :(得分:1)
任何使用命名空间的XML都必须声明这些命名空间,它总是需要自包含。
所以这个:
replacestring = '''<AP_PTO gml:id="DEAL123456789abc">
<new>This Element is new!</new>
</AP_PTO>'''
需要像这样:
replacestring = '''<AP_PTO gml:id="DEAL123456789abc" xmlns:gml="http://www.opengis.net/gml/3.2">
<new>This Element is new!</new>
</AP_PTO>'''
nsmap
的目的是让Python了解XML使用的命名空间,而不是相反。
事实上,这就是它被命名为“map”的原因,它允许您选择要在XPath中使用的前缀。它将名称空间URI映射到短句柄。这样:
obj.xpath('@foobar:id', namespaces=nsmap)
如果您的nsmap正确定义foobar
,将正常工作:
{'foobar': 'http://www.opengis.net/gml/3.2'}
在XML中使用什么前缀并不重要。前缀需要分别解析为正确的URI,并且URI需要相等。前缀本身不必相等。