Python 中字典列表的嵌套 XML 结构 3

Nested XML structures from list of dicts in Python 3

我有一个字典列表,我想从中创建一个 XML 结构。以下是我尝试过的示例。主要问题是我无法脱离元素“item”(我可能使用的术语不正确,请提前见谅):

import xml.etree.cElementTree as ET

mapping = [
    {"struct": "root\item\itemno"},
    {"struct": "root\item\itemdup"},
    {"struct": "root\item\edge\type"},
    {"struct": "root\item\edge\len\l1"},
    {"struct": "root\item\edge\len\l2"},
]

# The first item will always be the root
root = ET.Element(mapping[0]["struct"].split("\")[0])

for structure in mapping:
    structure = structure["struct"].split("\")
    # remove the first element, root, as this was already added
    del structure[0]
    iter = 1
    for element in structure:
        print("Element being processed", element)
        if not root.findall(element):
            if iter == 1:
                sub = ET.SubElement(root, element)
                print(f"iter {iter} - element not found in root {element} - Added to ROOT")
            else:
                ET.SubElement(sub, element)
                print(f"iter {iter} - element not found in root {element} - Added to SUB")
        else:
            print(f"iter {iter} - element found {element}")
        iter += 1

ET.dump(root)

我得到的结果如下:

<root>
  <item>
    <itemno />
    <itemdup />
    <edge />
    <type />
    <edge />
    <len />
    <l1 />
    <edge />
    <len />
    <l2 />
  </item>
</root>

我想要的是:

<root>
  <item>
    <itemno />
    <itemdup />
    <edge>
      <type />
      <len>
        <l1 />
        <l2 />
      </len>
    </edge>
  </item>
</root>

它开始很好,但是当它进入“类型”时,它进入了“项目”而不是“边缘”。

我放了一些打印语句来帮助我调试它,但我无法弄明白。

我已经在 SO 中研究过类似的问题,但主要问题是我的列表发生了变化,所以我并不总是知道我必须搜索的元素的名称以及放置它的位置。

您有嵌套元素,因此您应该以不同的方式创建它

对于每个结构第一组

 sub = root 

以后如果 item 不存在则创建新项目并将其作为 sub

 sub = ET.SubElement(sub, element)

如果 item 存在则获取它

 sub = item


import xml.etree.cElementTree as ET

mapping = [
    {"struct": "root\item\itemno"},
    {"struct": "root\item\itemdup"},
    {"struct": "root\item\edge\type"},
    {"struct": "root\item\edge\len\l1"},
    {"struct": "root\item\edge\len\l2"},
]

# The first item will always be the root
root = ET.Element(mapping[0]["struct"].split("\")[0])

for structure in mapping:
    structure = structure["struct"].split("\")
    # remove the first element, root, as this was already added
    del structure[0]

    sub = root
    for element in structure:
        print("Element:", element)
        item = sub.find(element)
        if not item:
            sub = ET.SubElement(sub, element)
        else:
            sub = item
    print('---')

#ET.dump(root)

from xml.dom import minidom
text = minidom.parseString(ET.tostring(root)).toprettyxml(indent="  ")
print(text)