首页 > 解决方案 > 使用python etree中的值对XML进行排序

问题描述

下面是我尝试使用 etree 排序的 xml,fullName 中的值被视为按字母顺序排序

<CustomLabels xmlns="http://soap.sforce.com/2006/04/metadata">
    <labels>
        <fullName>AnAutoQuote</fullName>
        <value>This is an automatically generated quote.</value>
        <language>en_US</language>
        <protected>false</protected>
        <shortDescription>Automatic Quote</shortDescription>
    </labels>
    <labels>
        <fullName>AManualQuote</fullName>
        <value>This is a manual quote.</value>
        <language>en_US</language>
        <protected>false</protected>
        <shortDescription>Manual Quote</shortDescription>
    </labels>
</CustomLabels>

我尝试过的代码,但它返回与输入中相同的 xml。这里 xml 包含为输入而读取的文件,解析器是编码设置为 utf-8 的 xml 解析器


root = objectify.string(xml, parse)

for r in root.iter("labels"):
    r[:] = sorted(r, key = lambda ch: -(ch.tag=="fullname"))

print(etree.toStrin(root).decode("utf-8))

标签: pythonlxmlelementtree

解决方案


root = objectify.fromstring(xml)
root.labels = sorted(root.labels, key=lambda tag: tag.fullName)

完整代码示例:

from lxml import objectify, etree

xml = '''<CustomLabels xmlns="http://soap.sforce.com/2006/04/metadata">
    <labels>
        <fullName>ZZZAManualQuote</fullName>
        <value>This is a manual quote.</value>
        <language>en_US</language>
        <protected>false</protected>
        <shortDescription>Manual Quote</shortDescription>
    </labels>
    <labels>
        <fullName>AnAutoQuote</fullName>
        <value>This is an automatically generated quote.</value>
        <language>en_US</language>
        <protected>false</protected>
        <shortDescription>Automatic Quote</shortDescription>
    </labels>
    <labels>
        <fullName>AManualQuote</fullName>
        <value>This is a manual quote.</value>
        <language>en_US</language>
        <protected>false</protected>
        <shortDescription>Manual Quote</shortDescription>
    </labels>
</CustomLabels>'''

root = objectify.fromstring(xml)
root.labels = sorted(root.labels, key=lambda tag: tag.fullName)

print(etree.tostring(root, pretty_print=True).decode('utf-8'))

输出

<CustomLabels xmlns="http://soap.sforce.com/2006/04/metadata">
  <labels>
    <fullName>AManualQuote</fullName>
    <value>This is a manual quote.</value>
    <language>en_US</language>
    <protected>false</protected>
    <shortDescription>Manual Quote</shortDescription>
  </labels>
  <labels>
    <fullName>AnAutoQuote</fullName>
    <value>This is an automatically generated quote.</value>
    <language>en_US</language>
    <protected>false</protected>
    <shortDescription>Automatic Quote</shortDescription>
  </labels>
  <labels>
    <fullName>ZZZAManualQuote</fullName>
    <value>This is a manual quote.</value>
    <language>en_US</language>
    <protected>false</protected>
    <shortDescription>Manual Quote</shortDescription>
  </labels>
</CustomLabels>

推荐阅读