简体   繁体   English

对子标记进行XML解析

[英]XML parsing on child tags

Below is the sample of my XML. 以下是我的XML示例。 There are many such similar cases. 有许多类似的情况。

<suite name="regression_1">
<test name="Login check" id="s1-t1">
    <tc name="Valid Username & Password">
        <message level="INFO" timestamp="20170726 14:25:39.778">Return: None</message>
        <status starttime="20170726 14:25:39.740" status="PASS"/>
    </tc>
    <tc name="Invalid Username or Password">
        <message level="INFO" timestamp="20170726 14:25:39.779">Return error</message>
        <tc name="Invalid password" library="avi_lib">
            <message level="TRACE" timestamp="20170726 14:25:47.769">Return error</message>
            <status starttime="20170726 14:25:39.779" status="FAIL"/>
        </tc>
        <status starttime="20170726 14:25:39.738" status="FAIL"/>
    </tc>
 <status status="FAIL"/>
</test>

</suite>

My requirement: Pass through the xml logs, note the tests, test cases and the test case status. 我的要求:通过xml日志,记录测试,测试用例和测试用例的状态。 If status is failed, then display for which test case and test suite its failed along with other relevant messages. 如果状态失败,则显示失败的测试用例和套件以及其他相关消息。

Issue i'm facing: I'm iterating over the test, collecting all the sub tests status and status. 我面临的问题:我正在遍历测试,收集所有子测试的状态和状态。 In the below code, if tc#2 is failed, output is giving for tc1 as I'm iterating for tc1 by collecting all the status which is in list. 在下面的代码中,如果tc#2失败,则由于我正在收集列表中的所有状态来迭代tc1,因此输出给出了tc1。 So the output is getting repeated. 因此输出将重复出现。

My desired output(Only for status="FAIL") 我想要的输出(仅用于status =“ FAIL”)

Test Name: Login check 测试名称:登录检查

Test case: Invalid username & Password 测试案例:无效的用户名和密码

Status: Fail 状态:失败

Messages: Return error 消息:返回错误

Below is my code: 下面是我的代码:

# !/usr/bin/python

from xml.dom.minidom import parse
import xml.dom.minidom
import time

DOMTree = xml.dom.minidom.parse("output.xml")
collection = DOMTree.documentElement
tc_entry = collection.getElementsByTagName("suite")


for tc in tc_entry:
    if tc.hasAttribute("name"):
       print ("Suite name: {}".format(tc.getAttribute("name")))
    tests = tc.getElementsByTagName('test')
    for test in tests:
        testcases = test.getElementsByTagName('tc')
        for tc_name in testcases:
            status = tc_name.getElementsByTagName('status')
            for state in status:
                if state.getAttribute("status") != "PASS":
                    print("Failed")
                    print("Test name: {}".format(test.getAttribute("name")))
                    print("Test case name: {}".format(tc_name.getAttribute("name")))
                    print("Status: {}".format(state.getAttribute("status")))

Don't know if I understood right... however, try with a recursive function like this: 不知道我是否理解正确...但是,尝试使用如下递归函数:

# !/usr/bin/python

from xml.dom.minidom import parse
import xml.dom.minidom
import time


def getStatusForNode(tc):
    status_to_be_returned = []
    is_just_father = False

    for child in tc.childNodes:
        if child.nodeName == "tc":
            is_just_father = True
            status_to_be_returned.append(getStatusForNode(child)[0])

    if not is_just_father:
        status = tc.getElementsByTagName('status')
        return [(tc, status)]

    return status_to_be_returned


DOMTree = xml.dom.minidom.parse("output.xml")
collection = DOMTree.documentElement
tc_entry = collection.getElementsByTagName("suite")


for tc in tc_entry:
    if tc.hasAttribute("name"):
       print("Suite name: {}".format(tc.getAttribute("name")))
    tests = tc.getElementsByTagName('test')
    for test in tests:

        for child in test.childNodes:
            if child.nodeName == "tc":
                children_status = getStatusForNode(child)
                for (tc_name, status) in children_status:
                    for state in status:
                        if state.getAttribute("status") != "PASS":
                            print("---")
                            print("Test name: {}".format(test.getAttribute("name")))
                            print("Test case name: {}".format(tc_name.getAttribute("name")))
                            print("Status: {}".format(state.getAttribute("status")))

Hope this helps 希望这可以帮助

Bye 再见
Dave 戴夫

I recommend using XPath expressions: 我建议使用XPath表达式:

Note: In my example, I am only working with a single suite element, so I refer to it as root - In your implementation you will want to iterate through all suite elements, thus root will differ, eg the line tests = root.findall('.//tc') would become tests = s.findall('.//tc') . 注:在我的例子,我只用一个单一的工作suite元素,所以我把它称为root -在您的实现,你会希望通过所有迭代suite元素,从而root会有所不同,例如行tests = root.findall('.//tc')将变成tests = s.findall('.//tc') I have commented out the lines I think you would use. 我已注释掉我认为您会使用的内容。

import xml.etree.ElementTree as et

tree = et.parse('some_file.xml')
root = tree.getroot()

# suites = root.findall('.//suite')

# for s in suites:

tests = root.findall('.//tc')  # Grab all 'tc' elements within a 'suite' element
test_name = root.find('test').attrib['name']

for tc in tests:
    status = tc.find('status').attrib['status'].lower()

    if 'fail' in status:
        tc_name = tc.attrib['name']
        msg = tc.find('message').text

        print("Test Name: {}\nTest Case: {}\nStatus: {}\nMessage: {}\n".format(
            test_name, tc_name, status.capitalize(), msg
        ))

Output: 输出:

Test Name: Login check
Test Case: Invalid Username or Password
Status: Fail
Message: Return error

Test Name: Login check
Test Case: Invalid password
Status: Fail
Message: Return error

Additionally, there is also XPath information within Python's xml.etree.ElementTree documentation. 此外,Python的xml.etree.ElementTree文档中还包含XPath信息。

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

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