繁体   English   中英

如何使用 python 中的 lxml 模块按子元素对 xml 文件进行排序?

[英]How can I sort my xml file by a subelement, using lxml module in python?

我正在使用 python 2。我使用 lxml 模块来处理 xml 文件。 我需要按标签“日期”对 xml 文件进行排序。

例如输入中的文件是这样的:

<?xml version="1.0" encoding="utf-8"?>
<ARCHIVE>
  <TCASE>
    <NAME>DISC</NAME>
    <DATE>04/30/2021 16:14:55</DATE>
    <VERDICT>PASS</VERDICT>
    <LOG>DISC_2021_04_30_16_14_55\DISC_2021_04_30_16_14_55.xml</LOG>
  </TCASE>
  <TCASE>
    <NAME>SEC</NAME>
    <DATE>04/30/2021 16:23:19</DATE>
    <VERDICT>INCONC</VERDICT>
    <LOG>SEC_2021_04_30_16_23_19\SEC_2021_04_30_16_23_19.xml</LOG>
  </TCASE>
  <TCASE>
    <NAME>SEC</NAME>
    <DATE>04/30/2021 16:17:01</DATE>
    <VERDICT>INCONC</VERDICT>
    <LOG>SEC_2021_04_30_16_17_01\EC_2021_04_30_16_17_01.xml</LOG>
  </TCASE>
</ARCHIVE>

处理后文件变成这样:

<?xml version="1.0" encoding="utf-8"?>
    <ARCHIVE>
      <TCASE>
        <NAME>DISC</NAME>
        <DATE>04/30/2021 16:14:55</DATE>
        <VERDICT>PASS</VERDICT>
        <LOG>DISC_2021_04_30_16_14_55\DISC_2021_04_30_16_14_55.xml</LOG>
      </TCASE>
      <TCASE>
        <NAME>SEC</NAME>
        <DATE>04/30/2021 16:17:01</DATE>
        <VERDICT>INCONC</VERDICT>
        <LOG>SEC_2021_04_30_16_17_01\EC_2021_04_30_16_17_01.xml</LOG>
      </TCASE>
      <TCASE>
        <NAME>SEC</NAME>
        <DATE>04/30/2021 16:23:19</DATE>
        <VERDICT>INCONC</VERDICT>
        <LOG>SEC_2021_04_30_16_23_19\SEC_2021_04_30_16_23_19.xml</LOG>
      </TCASE>
    </ARCHIVE>

谢谢你的帮助。

我尝试使用此代码。 但它不能很好地工作。

def getkey(self, elem):
    return datetime.strptime(elem.get('DATE'), "%d/%m/%y %H:%M:%S")

def produce_tc_log_XML(self, pathlayer):
        fileName = os.path.join(pathlayer, "tc_log.xml")
        if os.path.isfile(fileName):
            # print("File exist")
            tree = ET.parse(fileName)
            archive = tree.getroot()
            tcase = archive.find('TCASE')
            tcase[:] = sorted(tcase, key=self.getkey)
        else:
            # print("File not exist")
            archive = ET.Element("ARCHIVE")

        ET.indent(archive, space = "  ")
        xmlstr = ET.tostring(archive, xml_declaration = True, encoding = utf-8", pretty_print = True)
        with open(fileName, "w") as f:
            f.write(xmlstr)
            f.close()  

它必须是带有month/day/YEAR年的"%m/%d/%Y %H:%M:%S" - 你不能有month = 30
您必须使用大写Y来获得 4 位数的年份。

我必须在没有.find('TCASE').find('DATE').text而不是.get('DATE')情况下运行它


我的代码。 我只使用模块io来模拟文件。

text ='''<?xml version="1.0" encoding="utf-8"?>
<ARCHIVE>
  <TCASE>
    <NAME>DISC</NAME>
    <DATE>04/30/2021 16:14:55</DATE>
    <VERDICT>PASS</VERDICT>
    <LOG>DISC_2021_04_30_16_14_55\DISC_2021_04_30_16_14_55.xml</LOG>
  </TCASE>
  <TCASE>
    <NAME>SEC</NAME>
    <DATE>04/30/2021 16:23:19</DATE>
    <VERDICT>INCONC</VERDICT>
    <LOG>SEC_2021_04_30_16_23_19\SEC_2021_04_30_16_23_19.xml</LOG>
  </TCASE>
  <TCASE>
    <NAME>SEC</NAME>
    <DATE>04/30/2021 16:17:01</DATE>
    <VERDICT>INCONC</VERDICT>
    <LOG>SEC_2021_04_30_16_17_01\EC_2021_04_30_16_17_01.xml</LOG>
  </TCASE>
</ARCHIVE>'''

#from xml.etree import ElementTree as ET
import lxml.etree as ET
from datetime import datetime
import io

tree = ET.parse(io.BytesIO(text.encode()))  # Python 2 lxml, xml, Python 3

archive = tree.getroot()

def get_date(x):
    return datetime.strptime(x.find('DATE').text, "%m/%d/%Y %H:%M:%S")

archive[:] = sorted(archive, key=get_date)

print(ET.tostring(archive).decode())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM