XML etree动态抓取Python

2024-09-30 01:36:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用python库xml.etree.ElementTree解析xml文件。因此,我需要获取所有可能位于不同testsuite中的测试用例,这些测试用例位于testsuite后面。因此,我需要获得带有下一个字段(testcase.name、testcase)的字典列表和带有testsuite名称的列表

现在的输出示例:

[   {   'internal_id': '2503988',
    'name': 'C++ extentsion',
    'testsuite_path': [   '',
                          'Active CQM regression test suites',
                          'Temporary location of old data collection tests',
                          'Test folder for testsuite',
                          'name_of_testsuite']},
{   'internal_id': '1680735',
    'name': 'JAVA: DELETE with CURSOR OF. Dynamic DELETE with CURRENT OF '
            'clause',
    'testsuite_path': [   '',
                          'Active CQM regression test suites',
                          'Temporary location of old data collection tests',
                          'Test folder for testsuite',
                          'name_of_testsuite']},
{   'internal_id': '1680736',
    'name': 'Python interpreter',
    'testsuite_path': [   '',
                          'Active CQM regression test suites',
                          'Temporary location of old data collection tests',
                          'Test folder for testsuite',
                          'name_of_testsuite']},
{   'internal_id': '5684390',
    'name': 'Next test case is here',
    'testsuite_path': [   '',
                          'Active CQM regression test suites',
                          'Temporary location of old data collection tests',
                          'Test folder for testsuite',
                          'name_of_testsuite']},
{   'internal_id': '880055',
    'name': 'Second test case is here',
    'testsuite_path': [   '',
                          'Active CQM regression test suites',
                          'Temporary location of old data collection tests',
                          'Test folder for testsuite',
                          'name_of_testsuite']},
{   'internal_id': '999443',
    'name': 'test data',
    'testsuite_path': [   '',
                          'Active CQM regression test suites',
                          'Temporary location of old data collection tests',
                          'Test folder for testsuite',
                          'name_of_testsuite']}]

输出,这是我需要得到的

 [   {   'internal_id': '2503988',
    'name': 'C++ extentsion',
    'testsuite_path': [   '',
                          'Active CQM regression test suites'
                          ]},
{   'internal_id': '1680735',
    'name': 'JAVA: DELETE with CURSOR OF. Dynamic DELETE with CURRENT OF '
            'clause',
    'testsuite_path': [   '',
                          'Active CQM regression test suites',
                          'Temporary location of old data collection tests'
                      ]},
{   'internal_id': '1680736',
    'name': 'Python interpreter',
    'testsuite_path': [   '',
                          'Active CQM regression test suites',
                          'Temporary location of old data collection tests'
                      ]},
{   'internal_id': '5684390',
    'name': 'Next test case is here',
    'testsuite_path': [   '',
                          'Active CQM regression test suites',
                          'Test folder for testsuite'
                      ]},
{   'internal_id': '880055',
    'name': 'Second test case is here',
    'testsuite_path': [   '',
                          'Active CQM regression test suites',
                          'Test folder for testsuite'
                      ]},
{   'internal_id': '999443',
    'name': 'test data',
    'testsuite_path': [   '',
                          'name_of_testsuite'
                      ]}

]

以下是xml文件的一个示例:

<?xml version="1.0" encoding="UTF-8"?>
<testplan>
    <name><![CDATA[]]></name>
    
    <testproject>
        <name><![CDATA[CQM]]></name>        
        <prefix><![CDATA[CQM]]></prefix>        
        <internal_id><![CDATA[500348]]></internal_id>
    </testproject>

    <testsuite id="" name="">
        <testsuite name="Active CQM regression test suites" >
            <node_order><![CDATA[0]]></node_order>
            <details><![CDATA[]]></details>
            <testsuite name="Temporary location of old data collection tests" >
                <node_order><![CDATA[1]]></node_order>
                <details><![CDATA[]]></details>
                <testcase internalid="1680735" name="JAVA: DELETE with CURSOR OF. Dynamic DELETE with CURRENT OF clause">
                    <externalid><![CDATA[14814]]></externalid>
                </testcase>
                <testcase internalid="1680736" name="Python interpreter">
                    <externalid><![CDATA[15688]]></externalid>
                </testcase>
            </testsuite>
            <testcase internalid="2503988" name="C++ extentsion">
                    <externalid><![CDATA[95476]]></externalid>
            </testcase>
            <testsuite name="Test folder for testsuite" >
                <node_order><![CDATA[5]]></node_order>
                <details><![CDATA[]]></details>
                <testcase internalid="5684390" name="Next test case is here">
                    <externalid><![CDATA[14814]]></externalid>
                </testcase>
                <testcase internalid="880055" name="Second test case is here">
                    <externalid><![CDATA[43267]]></externalid>
                </testcase>
            </testsuite>
        </testsuite>
        <testsuite name="name_of_testsuite">
            <testcase internalid="999443" name="test data">
                <externalid><![CDATA[63333]]></externalid>
            </testcase>
        </testsuite>
    </testsuite>
</testplan>        

我现在的代码非常糟糕,我只能得到所有的testsuite,但不知道如何前进:

import xml.etree.ElementTree as ET
def get_all_testsuites(testcases, result_testcase_list = [], testcase_path=[]):
   testsuites = testcases.findall('testsuite')

   if len(testsuites):
       for testsuite in testsuites:
           testcases = testsuite.findall('testcase')
           testcase_path.append(testsuite.get('name'))

           if len(testcases):
               for testcase in testcases:
                   result_testcase_list.append({'name': testcase.get('name'), 'internal_id': testcase.get('internalid'), 'testsuite_path': testcase_path})

        
           get_all_testsuites(testsuite, result_testcase_list, testcase_path)
    else:
        pass

    return result_testcase_list

if __name__ == '__main__':
    testcases = ET.parse('testcases.xml')
    print(get_all_testsuites(testcases))
 

更新

升级了代码,但返回了错误的路径

此外,我将感谢任何帮助,谢谢


Tags: ofpathnametestiddatatestcaseactive
1条回答
网友
1楼 · 发布于 2024-09-30 01:36:12

你的代码看起来真的很完美。唯一的问题是指针的概念

当您将testcase_path变量分配给最终对象result_testcase_list时,它不存储变量的当前值,而是存储指向该变量的指针(内存地址),这意味着,该变量未来的每个变化都将反映在最终对象分配的每个点上

要解决这个问题,您需要以不可变的方式创建testcase_path的新副本

def get_all_testsuites(testcases, result_testcase_list = [], testcase_path=[]):
    testsuites = testcases.findall('testsuite')

    if len(testsuites):
        for testsuite in testsuites:
            testcases = testsuite.findall('testcase')
            # creating a brand new variable and NOT using a mutation method 
            #    like 'append', but operating them with '+' 
            current_path = testcase_path + [testsuite.get('name')]
 
            if len(testcases):
                for testcase in testcases:
                    # using the new variable here ...
                    result_testcase_list.append({'name': testcase.get('name'), 'internal_id': testcase.get('internalid'), 'testsuite_path': current_path})
                # ... and here
            get_all_testsuites(testsuite, result_testcase_list, current_path)
    else:
        pass

    return result_testcase_list

更新:更正了调用递归时的缩进

相关问题 更多 >

    热门问题