[英]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.