【问题标题】:XML etree dynamical scraping PythonXML etree 动态抓取 Python
【发布时间】:2021-03-25 09:47:26
【问题描述】:

我正在尝试使用 python 库 xml.etree.ElementTree 解析 xml 文件。结果,我需要获取所有可能位于测试套件后面的不同测试套件中的测试用例。结果,我需要获取带有下一个字段(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>        

我现在的代码很差,我只能得到所有的测试套件,但不知道如何前进:

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))
 

更新

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

另外,我将不胜感激,谢谢。

【问题讨论】:

    标签: python xml xml.etree


    【解决方案1】:

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

    当您将 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
    
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-18
      • 2014-04-28
      • 2014-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-27
      • 2015-06-26
      相关资源
      最近更新 更多