使用 Python 中的 ElementTree 按顺序将标签分配给 XML

Assigning tags by order to XML using ElementTree in Python

我有一个 XML 文件,其中包含多个 parents 和嵌套 children,我想添加一个新的“订单”标签来指示他们的订单。

目前我有类似的东西

<root>
      <level id='FRUITS'>
        <level id='APPLE'>
          <heading>APPLE HEADER </heading>
          <level id='APPLE_ONE'>
            <file fileName='APPLE_ONE_I' />
            <heading>This is Apple One I.</heading>
            <file fileName='APPLE_ONE_II' />
            <heading>This is Apple One II.</heading>
          </level>
          <level id='APPLE_TWO'>
            <file fileName='APPLE_TWO_II' />
            <heading>This is Apple One I.</heading>
          </level>
        </level>
        <level id='ORANGE'>
          <heading>ORANGE HEADER</heading>
          <level id='ORANGE_ONE'>
            <file fileName='ORANGE_ONE_I' />
            <heading>This is Orange One I.</heading>
          </level>
        </level>
      </level>
    </root>

我需要为 ID 而不是文件的顺序添加一个指示符。这样看起来像

<root>
      <level id='FRUITS' order='1'>
        <level id='APPLE' order='1'>
          <heading>APPLE HEADER</heading>
          <level id='APPLE_ONE' order='1'>
            <file fileName='APPLE_ONE_I' />
            <heading>This is Apple One I.</heading>
            <file fileName='APPLE_ONE_II' />
            <heading>This is Apple One II.</heading>
          </level>
          <level id='APPLE_TWO' order='2'>
            <file fileName='APPLE_TWO_II' />
            <heading>This is Apple One I.</heading>
          </level>
        </level>
        <level id='ORANGE' order='2'>
          <heading>ORANGE HEADER</heading>
          <level id='ORANGE_ONE' order='1'>
            <file fileName='ORANGE_ONE_I' />
            <heading>This is Orange One I.</heading>
          </level>
        </level>
      </level>
    </root>

一种方法是在 lxml 中使用 xpath() 来获取 preceding-sibling levels 的计数以确定“order”的值...

from lxml import etree

xml = """<root>
      <level id='FRUITS'>
        <level id='APPLE'>
          <heading>APPLE HEADER </heading>
          <level id='APPLE_ONE'>
            <file fileName='APPLE_ONE_I' />
            <heading>This is Apple One I.</heading>
            <file fileName='APPLE_ONE_II' />
            <heading>This is Apple One II.</heading>
          </level>
          <level id='APPLE_TWO'>
            <file fileName='APPLE_TWO_II' />
            <heading>This is Apple One I.</heading>
          </level>
        </level>
        <level id='ORANGE'>
          <heading>ORANGE HEADER</heading>
          <level id='ORANGE_ONE'>
            <file fileName='ORANGE_ONE_I' />
            <heading>This is Orange One I.</heading>
          </level>
        </level>
      </level>
    </root>
"""

tree = etree.fromstring(xml)

for level in tree.xpath(".//level"):
    level.set("order", str(len(level.xpath("preceding-sibling::level")) + 1))

print(etree.tostring(tree).decode())

打印输出...

<root>
      <level id="FRUITS" order="1">
        <level id="APPLE" order="1">
          <heading>APPLE HEADER </heading>
          <level id="APPLE_ONE" order="1">
            <file fileName="APPLE_ONE_I"/>
            <heading>This is Apple One I.</heading>
            <file fileName="APPLE_ONE_II"/>
            <heading>This is Apple One II.</heading>
          </level>
          <level id="APPLE_TWO" order="2">
            <file fileName="APPLE_TWO_II"/>
            <heading>This is Apple One I.</heading>
          </level>
        </level>
        <level id="ORANGE" order="2">
          <heading>ORANGE HEADER</heading>
          <level id="ORANGE_ONE" order="1">
            <file fileName="ORANGE_ONE_I"/>
            <heading>This is Orange One I.</heading>
          </level>
        </level>
      </level>
    </root>