代码之家  ›  专栏  ›  技术社区  ›  amrezzd

在Python中通过ElementTree解析xml时如何保留名称空间

  •  0
  • amrezzd  · 技术社区  · 6 年前

    ElementTree :

    <root xmlns:prefix="URI">
      <child company:name="***"/>
      ...
    </root> 
    

    我正在对XML文件进行如下修改:

    import xml.etree.ElementTree as ET
    tree = ET.parse('filename.xml')
    # XML modification here
    # save the modifications
    tree.write('filename.xml')
    

    然后,XML文件如下所示:

    <root xmlns:ns0="URI">
      <child ns0:name="***"/>
      ...
    </root>
    

    正如你所看到的,名字 prefix 改为 ns0 . 我知道使用 ET.register_namespace() 如上所述 here .

    问题在于 ET.register_namespace() 这是:

    1. 前缀 URI
    2. 它不能与默认命名空间一起使用。

    e、 g.如果xml看起来像:

    <root xmlns="http://uri">
        <child name="name">
        ...
        </child>
    </root>
    

    它将转变为:

    <ns0:root xmlns:ns0="http://uri">
        <ns0:child name="name">
        ...
        </ns0:child>
    </ns0:root>
    

    如您所见,默认名称空间更改为

    有什么办法可以解决这个问题吗 ?

    1 回复  |  直到 4 年前
        1
  •  18
  •   amrezzd    3 年前

    ElementTree将替换那些未注册到的命名空间前缀 ET.register_namespace . 要保留名称空间前缀,需要先注册它,然后再将修改写入文件。以下方法执行此任务并全局注册所有名称空间,

    def register_all_namespaces(filename):
        namespaces = dict([node for _, node in ET.iterparse(filename, events=['start-ns'])])
        for ns in namespaces:
            ET.register_namespace(ns, namespaces[ns])
    

    此方法应在之前调用 ET.parse 方法,以便名称空间保持不变,

    import xml.etree.ElementTree as ET
    register_all_namespaces('filename.xml')
    tree = ET.parse('filename.xml')
    # XML modification here
    # save the modifications
    tree.write('filename.xml')