【问题标题】:LXML: Replacing elements from string with namespacesLXML:用命名空间替换字符串中的元素
【发布时间】:2017-11-09 17:45:23
【问题描述】:

如何使用相同的命名空间将某个元素替换为字符串sn-p?

<!-- 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'}

如果我从替换字符串中删除 gml: Prefix,则循环按预期工作。该字符串用给定的 ID 替换前一个元素。但是有了前缀,我得到了一个: XMLSyntaxError:AP_PTO 上 id 的命名空间前缀 gml 未定义,第 2 行,第 34 列

如何告诉 lxml 从源文件中使用 nsmap 中定义的命名空间?

【问题讨论】:

    标签: python xml lxml


    【解决方案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 需要相等。前缀本身不必相等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-26
      • 1970-01-01
      • 2020-10-05
      • 2021-03-20
      • 2012-03-19
      • 2011-04-03
      • 2013-01-14
      • 1970-01-01
      相关资源
      最近更新 更多