如何使用lxml插入具有正确名称空间前缀的属性

问题描述 投票:1回答:1

有没有一种方法,可以使用lxml插入具有正确名称空间的XML属性?

例如,我想使用XLink在XML文档中插入链接。我需要做的就是在某些元素中插入{http://www.w3.org/1999/xlink}href属性。我想使用xlink前缀,但是lxml会生成诸如“ ns0”,“ ns1”…]之类的前缀。

这是我尝试过的:

from lxml import etree

#: Name (and namespace) of the *href* attribute use to insert links.
HREF_ATTR = etree.QName("http://www.w3.org/1999/xlink", "href").text

content = """\
<body>
<p>Link to <span>StackOverflow</span></p>
<p>Link to <span>Google</span></p>
</body>
"""

targets = ["https://stackoverflow.com", "https://www.google.fr"]
body_elem = etree.XML(content)
for span_elem, target in zip(body_elem.iter("span"), targets):
    span_elem.attrib[HREF_ATTR] = target

etree.dump(body_elem)

转储看起来像这样:

<body>
<p>link to <span xmlns:ns0="http://www.w3.org/1999/xlink"
                 ns0:href="https://stackoverflow.com">stackoverflow</span></p>
<p>link to <span xmlns:ns1="http://www.w3.org/1999/xlink"
                 ns1:href="https://www.google.fr">google</span></p>
</body>

我找到了一种通过在根元素中插入和删除属性来分解名称空间的方法,如下所示:

# trick to declare the XLink namespace globally (only one time).
body_elem = etree.XML(content)
body_elem.attrib[HREF_ATTR] = ""
del body_elem.attrib[HREF_ATTR]

targets = ["https://stackoverflow.com", "https://www.google.fr"]
for span_elem, target in zip(body_elem.iter("span"), targets):
    span_elem.attrib[HREF_ATTR] = target

etree.dump(body_elem)

这很丑,但是它可以工作,我只需要做一次。我得到:

<body xmlns:ns0="http://www.w3.org/1999/xlink">
<p>Link to <span ns0:href="https://stackoverflow.com">StackOverflow</span></p>
<p>Link to <span ns0:href="https://www.google.fr">Google</span></p>
</body>

但是问题仍然存在:如何将这个“ ns0”前缀转换为“ xlink”?

是否有一种使用lxml插入具有正确名称空间的XML属性的方法?例如,我想使用XLink在XML文档中插入链接。我需要做的就是插入{http://www.w3.org / ...

python xml lxml xml-namespaces
1个回答
1
投票

使用@mzjn建议的register_namespace

© www.soinside.com 2019 - 2024. All rights reserved.