Python - 使用 ElementTree 将输出 XML 命名空间定义保留在非根节点上

Python - keep output XML namespace definitions at non-root nodes with ElementTree

提问人:bproxauf 提问时间:11/13/2023 更新时间:11/13/2023 访问量:54

问:

我想使用 xml.etree.ElementTree(简称:ElementTree)从 Python 中修改后的输入 XML 生成输出 XML。输入 XML 具有多个命名空间,输出 XML 也应具有这些命名空间,这些命名空间定义在与输入 XML 相同的节点上;由于特定原因,后者很重要。但是,默认情况下,ElementTree 在根节点上设置命名空间。如果可能,我该如何防止这种情况发生?下面是一个最小的示例(不对输入 XML 进行修改):

读取 + 写入 XML (demo_input_xml.py):

import sys
import xml.etree.ElementTree as ET

infile = sys.argv[1]
outfile = sys.argv[2]

# read the input XML file
tree = ET.parse(infile)
# get the tree root
root = tree.getroot()

# insert modifications to XML here

# open the output file and write out the new XML tree
ofile = open(outfile, 'w')
tree.write(ofile)
ofile.close()

输入 XML (demo_temp_input.xml):

<?xml version="1.0" encoding="UTF-8"?>
<tag0 xmlns="namespace0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="someLocation0">
  <tag1a>someText</tag1a>
  <tag1b xmlns="namespace1" xmlns:n1="namespace2" xsi:schemaLocation="someLocation1">
    <tag2>
      <tag3 xmlns="namespace3" xsi:schemaLocation="someLocation2">
      </tag3>
    </tag2>
  </tag1b>
</tag0>

实际输出 XML (demo_temp_output.xml):

<ns0:tag0 xmlns:ns0="namespace0" xmlns:ns2="namespace1" xmlns:ns3="namespace3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="someLocation0">
  <ns0:tag1a>someText</ns0:tag1a>
  <ns2:tag1b xsi:schemaLocation="someLocation1">
    <ns2:tag2>
      <ns3:tag3 xsi:schemaLocation="someLocation2">
      </ns3:tag3>
    </ns2:tag2>
  </ns2:tag1b>
</ns0:tag0>

所需的输出 XML:

<ns0:tag0 xmlns:ns0="namespace0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="someLocation0">
  <ns0:tag1a>someText</ns0:tag1a>
  <ns2:tag1b xmlns:ns2="namespace1" xsi:schemaLocation="someLocation1">
    <ns2:tag2>
      <ns3:tag3 xmlns:ns3="namespace3" xsi:schemaLocation="someLocation2">
      </ns3:tag3>
    </ns2:tag2>
  </ns2:tag1b>
</ns0:tag0>

需要考虑的事项:

  • 使用的 python 版本是 2.7.18。
  • lxml 软件包不可用,我没有安装它的权限。
  • 输入 XML 具有多个默认命名空间(即没有前缀)。理想情况下,输出 XML 也将具有多个默认命名空间(我已经尝试过 ET.register_namespaces()ET._namespace_map,但没有成功),但这不是优先事项。因此,其他命名空间前缀,以及由 ElementTree 生成的前缀,例如 ns0、ns2 等,原则上是可以的(附带问题:为什么 ElementTree 不使用前缀 ns1
  • ElementTree 不存储未使用的命名空间(在最小示例中,前缀为 n1,“namespace2”)。一旦该命名空间下的任何标记在输入 XML 中使用前缀,ElementTree 就会将此类带有 (input) 前缀的命名空间放在输出 XML 的根节点上。我原以为默认行为是保留任何命名空间,无论它们以后是否被使用,但这很好。
  • ElementTree 从输入 XML 中省略 XML 版本标头行;这很好。
python xml xml解析 元素树

评论


答: 暂无答案