python - 在 Python 中使用 ElementTree 按顺序将标签分配给 XML
问题描述
我有一个包含多个父级嵌套子级的 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>
我需要为 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() 来获取先前兄弟level
的计数以确定“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>
推荐阅读
- php - 带有命名参数的 PHP PDO 中的存储过程
- r - Zelen 的获胜者规则随机化方案
- julia - `xcrun: error: invalid active development` 运行 make.jl 以生成 Julia 文档时
- node.js - 如何在 React Native 上将 JWT 令牌与 axios 一起使用
- reactjs - 如何使用基于状态的 props 组织 React 动态组件
- javascript - 在反应中重用
- javascript - 通过给定的货币数组计算变化
- mysql - 如何选择按日期列 desc 排序的不同记录 - Laravel
- azure - Azure Runbook 自动化 - Invoke-AzureRmVMRunCommand 错误
- mysql - 如何在mysql中的union子句中排序结果