Python 将嵌套 XML 与未排序的兄弟姐妹一起排序

问题描述 投票:0回答:1

我需要使用 Elementtree 按 reqdate 对以下示例 XML 的“行”元素进行排序(desc - 从最近到最旧)。

<doc>
    <header>
        <ordernum>1234</ordernum>
        <customer>1</customer>
        <line>
            <lineno>1</lineno>
            <reqdat>2024-01-01</reqdat>
        </line>
        <line>
            <lineno>2</lineno>
            <reqdat>2024-03-01</reqdat>
        </line>
        <line>
            <lineno>3</lineno>
            <reqdat>2024-02-01</reqdat>
        </line>
    </header>
</doc>

我正在寻找的结果如下。

<doc>
    <header>
        <ordernum>1234</ordernum>
        <customer>1</customer>
        <line>
            <lineno>2</lineno>
            <reqdat>2024-03-01</reqdat>
        </line>
        <line>
            <lineno>3</lineno>
            <reqdat>2024-02-01</reqdat>
        </line>
        <line>
            <lineno>1</lineno>
            <reqdat>2024-01-01</reqdat>
        </line>
    </header>
</doc>

用例是将其发送到使用 XML 中的顺序的打印机,并且需要按此顺序打印各行。

我正在尝试排序函数和 lambda 排序,但还没有弄清楚。

python xml sorting elementtree
1个回答
0
投票

尝试:

import xml.etree.ElementTree as ET

xml_string = """
<doc>
    <header>
        <ordernum>1234</ordernum>
        <customer>1</customer>
        <line>
            <lineno>1</lineno>
            <reqdat>2024-01-01</reqdat>
        </line>
        <line>
            <lineno>2</lineno>
            <reqdat>2024-03-01</reqdat>
        </line>
        <line>
            <lineno>3</lineno>
            <reqdat>2024-02-01</reqdat>
        </line>
    </header>
</doc>
"""

root = ET.fromstring(xml_string)


header = root.find(".//header")
lines = header.findall(".//line")
lines = sorted(lines, key=lambda tag: tag.find("reqdat").text, reverse=True)

for l in list(header):
    if l.tag == "line":
        header.remove(l)

for l in lines:
    header.append(l)

print(ET.tostring(root, encoding="unicode"))

打印:

<doc>
    <header>
        <ordernum>1234</ordernum>
        <customer>1</customer>
        <line>
            <lineno>2</lineno>
            <reqdat>2024-03-01</reqdat>
        </line>
        <line>
            <lineno>3</lineno>
            <reqdat>2024-02-01</reqdat>
        </line>
    <line>
            <lineno>1</lineno>
            <reqdat>2024-01-01</reqdat>
        </line>
        </header>
</doc>
© www.soinside.com 2019 - 2024. All rights reserved.