python - 使用 xml.etree 保留命名空间

标签 python xml namespaces elementtree

在源文件的根元素中定义命名空间时,lxml在输出中重现所有这些。我需要用 xml.etree 来做这件事.更好的是只输出那些使用过的,但是 xml.etree没有找到所有这些。

一种解决方案是使用 root.set() 强行添加命名空间.但是,这会复制 xml.etree 的所有命名空间。确实找到了,如下图。

适合在命令提示符中粘贴的完整示例:

import xml.etree.ElementTree as ET
try:
    from io import StringIO
except ImportError:
    from StringIO import StringIO

def get_namespaces(sourcestring):
    sourcefile = StringIO(sourcestring)
    return dict(
        [node for _, node in ET.iterparse(sourcefile, events=['start-ns'])])

ET._namespace_map = dict()  # remove any previously registered namespaces
sourcetext = (
    '<desc xmlns="uri_a" xmlns:b="uri_b" xmlns:c="uri_c"'
    ' b:foo="c:bar">a</desc>')
source = ET.fromstring(sourcetext)
namespaces = get_namespaces(sourcetext)
for prefix, uri in namespaces.items():
    ET.register_namespace(prefix, uri)
    if prefix:
        tag = 'xmlns:' + prefix
    else:
        tag = 'xmlns'
    source.set(tag, uri)

print(ET.tostring(source, encoding='unicode'))

结果,导致我的应用程序失败:
<desc xmlns="uri_a" xmlns:b="uri_b" xmlns="uri_a" xmlns:b="uri_b" xmlns:c="uri_c" b:foo="c:bar">a</desc>

这类似于 Forcing xml.etree to output "unused" namespaces ,但命名空间来自源文件,因此 Python 代码不知道它们。

最佳答案

首先,在不添加缺少的命名空间的情况下生成输出。获取从该输出中找到的命名空间。然后,通过添加未找到的命名空间来生成最终输出。

def add_namespaces_not_found(root):
    result_with_namespaces_found = ET.tostring(root, encoding='unicode')
    namespaces_found = get_namespaces(result_with_namespaces_found)
    for prefix, uri in namespaces.items():
        if prefix not in namespaces_found:
            if prefix:
                tag = 'xmlns:' + prefix
            else:
                tag = 'xmlns'
            root.set(tag, uri)

结果:
<desc xmlns="uri_a" xmlns:b="uri_b" xmlns:c="uri_c" b:foo="c:bar">a</desc>

欢迎不需要生成两次输出的解决方案。

关于python - 使用 xml.etree 保留命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62139743/

相关文章:

Java,dom4j : how to add inline element (b, i,u) 位于文本中间

c# - 从 C# 中的 XML 填充下拉列表

python - 安装 Django 时出错

python - 如何在Python中引用列表中的字符串

python - 如何离线安装 Pytorch?

javascript - 将变量加载到异步 JS 中?

c# - 如何在 C# Express 2008 中添加命名空间?

python - 如何将字符串中的小写字符和大写字符分开?

xml - 如何在 actionscript 3 中设置 xml 元素的变量属性?

c++ - 命名空间菜鸟问题 : two cpp files sharing the same namespace have the same variable