【问题标题】:Python how to order Xml file according to CSV ordering?Python如何根据CSV排序订购Xml文件?
【发布时间】:2021-09-18 02:31:50
【问题描述】:

我有这个 XML 文件:- final.xml

<?xml version="1.0"?>
<TestSuite Name="DM123">
  <Group Name="TestRoot" ExecutionPolicy="AnyDeviceAnyOrder">
    <Parameters>
      <Parameter Type="Integer" Name="maxA" Value="1" />
      <Parameter Type="Integer" Name="MaxB" Value="120" />
      <Parameter Type="String" Name="MaxC" Value="integration" />
    </Parameters>
    <Children>
      <Test Name="Test1" Namespace="TestCases">
        <Parameters>
           <Parameter Type="Device" Name="Device">
             <Requirements>
               <Requirement TypeId="a76" Source="User" />
               <Requirement TypeId="2c9" Source="User" />
             </Requirements>
           </Parameter>
        </Parameters>
      </Test>
      <Test Name="Test5" Namespace="TestCases">
        <Parameters>
           <Parameter Type="Dev" Name="Dev">
               <Requirements>
                 <Requirement TypeId="a76" Source="User" />
                 <Requirement TypeId="2c9" Source="User" />
               </Requirements>
           </Parameter>
        </Parameters>
      </Test>
      <Test Name="Test6" Namespace="TestCases">
            <Parameters>
              <Parameter Type="Dev" Name="Dev">
                <Requirements>
                  <Requirement TypeId="a76" Source="User" />
                  <Requirement TypeId="2c9" Source="User" />
                </Requirements>
              </Parameter>
              <Parameter Type="Integer" Name="expected amount of images" Value="10" />
            </Parameters>
      </Test>
   </Children>
  </Group>
  <Models>
    <Model Name="DD1" />
  </Models>
</TestSuite>

xml 文件包含测试用例名称及其详细信息。这只是一个示例,但我在 xml 文件中有数千个这样的测试用例。

我有一个 CSV 文件,它也包含相同的测试用例,但按顺序排列。顺序是使用一些特定参数定义的,例如首先处理最短处理时间:-

Id TestName
0    Test5
1    Test1
3    Test6

我想根据 CSV 文件订购 xml 文件。我是python的初学者。我怎么能在python中做到这一点?提前致谢

期望的输出:-

<?xml version="1.0"?>
<TestSuite Name="DM123">
  <Group Name="TestRoot" ExecutionPolicy="AnyDeviceAnyOrder">
    <Parameters>
      <Parameter Type="Integer" Name="maxA" Value="1" />
      <Parameter Type="Integer" Name="MaxB" Value="120" />
      <Parameter Type="String" Name="MaxC" Value="integration" />
    </Parameters>
    <Children>
      <Test Name="Test5" Namespace="TestCases">
        <Parameters>
           <Parameter Type="Dev" Name="Dev">
               <Requirements>
                 <Requirement TypeId="a76" Source="User" />
                 <Requirement TypeId="2c9" Source="User" />
               </Requirements>
           </Parameter>
        </Parameters>
      </Test>
      <Test Name="Test1" Namespace="TestCases">
        <Parameters>
           <Parameter Type="Device" Name="Device">
             <Requirements>
               <Requirement TypeId="a76" Source="User" />
               <Requirement TypeId="2c9" Source="User" />
             </Requirements>
           </Parameter>
        </Parameters>
      </Test>
      <Test Name="Test6" Namespace="TestCases">
            <Parameters>
              <Parameter Type="Dev" Name="Dev">
                <Requirements>
                  <Requirement TypeId="a76" Source="User" />
                  <Requirement TypeId="2c9" Source="User" />
                </Requirements>
              </Parameter>
              <Parameter Type="Integer" Name="expected amount of images" Value="10" />
            </Parameters>
      </Test>
   </Children>
  </Group>
  <Models>
    <Model Name="DD1" />
  </Models>
</TestSuite>

【问题讨论】:

    标签: python pandas xml csv


    【解决方案1】:

    一种可能的方法是使用 BeautifulSoup 来帮助进行 XML 解析。可以使用以下方式安装:

    pip install beautifulsoup4
    

    代码:

    from bs4 import BeautifulSoup
    import csv
    import glob
    
    
    tests = {}
    
    # Read in the XML files and parse them
    
    for xml_filename in glob.glob('*.xml'):
        print(f'Parsing {xml_filename}')
        
        with open(xml_filename) as f_input:
            soup = BeautifulSoup(f_input, 'xml')
            
        # Store all test tags in a dictionary 
        # (this assumes each test has a unique name)
    
        for test in soup.find_all('Test'):
            tests[test['Name']] = test
    
    # Locate the children tag and empty it
    
    children = soup.find('Children')
    children.clear()
    
    # Read in the ordering CSV and append the tests in the required order into
    # the children tag
    
    with open('order.csv', newline='') as f_order:
        csv_order = csv.reader(f_order)
        header = next(csv_order)
        
        for id, test_name in csv_order:
            try:
                children.append(tests.pop(test_name))
            except KeyError:
                print(f"Test '{test_name}' not present")
     
    # Add any remaining tests not listed in the CSV
        
    for test in tests.values():
        children.append(test)
        
    # Write the modified xml
    
    with open('output.xml', 'w') as f_output:
        f_output.write(str(soup))
    

    XML 的缩进将被修改,但结构将保持不变。通过将输出写入更改为:

    f_output.write(soup.prettify())
    

    它首先将所有 XML 文件中的所有测试存储在 Python 字典中。然后在读取您的订购 CSV 文件时,它使用 pop 从字典中读取每个测试并将其附加到子标签中。通过使用pop(),它还会从字典中删除测试。然后可以将字典中剩余的任何测试(不在排序 CSV 中)添加到末尾(如果需要)。

    【讨论】:

    • 我有多个 xml 文件,如何一个一个打开,然后在同一个文件中重新写入?
    • 您可以使用glob.glob('*.xml') 遍历文件。我假设所有测试名称都是唯一的?
    • 我收到错误 KeyError Traceback(最近一次调用最后一次) in 27 28 for Id, test_name in header: ---> 29 children.append (tests.pop(test_name)) 30 31 # 添加任何未在 CSV KeyError 中列出的剩余测试:'d'
    • 如果order.csv 中的测试名称在input.xml 中不存在,就会发生这种情况。我添加了一个异常处理来显示何时发生这种情况
    • 它给了我这个错误:-TypeError Traceback(最近一次调用最后一次) in 28 for TestCaseName in csv_order: 29 try: ---> 30 children.append(tests.pop(TestCaseName)) 31 除了 KeyError: 32 print(f"Test '{TestCaseName}' not present") TypeError: unhashable type: 'list'
    猜你喜欢
    • 2021-09-18
    • 2013-06-10
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 1970-01-01
    • 2011-05-15
    相关资源
    最近更新 更多