2017-07-27 27 views
0

以下は私のXMLのサンプルです。このような場合も多い。子タグのXML解析

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

私の要件: テスト、テストケースとテストケースの状態に注意し、XMLログを通過します。ステータスが失敗した場合は、テストケースとテストスイートが失敗したことを他の関連メッセージとともに表示します。

問題私は直面しています:私はすべてのサブテストのステータスとステータスを収集し、テストを繰り返しています。下のコードでは、tc#2が失敗した場合、リストにあるすべてのステータスを収集してtc1を繰り返しているので、tc1の出力が与えられます。したがって、出力が繰り返されています。

マイ所望の出力(ステータスのみのために= "FAIL")

テスト名:無効なユーザー名&パスワード

ステータス::リターン:

メッセージを失敗ログイン

テストケースをチェックエラー

以下は私のコードです:

# !/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"))) 
+0

希望の出力と現在の出力を2つのコードブロックで投稿できますか? – Harrichael

答えて

0

私は右理解している場合...しかし、このような再帰関数としてみてください知ってはいけない:

# !/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"))) 

希望これは

を助けさようなら
デイブ

+0

@Dave、それは完全に動作します。あなたに感謝します。 – Yadunandana

+0

喜んで助けてくれました。 – mastro35

0

私がお勧めしますXPath式を使用して:

注:私の例では、私はただ1つのsuite要素ですので、rootと呼びます。実装では、すべてsuite要素を繰り返し処理する必要があるため、rootは異なります。線tests = root.findall('.//tc')tests = s.findall('.//tc')になります。私はあなたが使うだろうと思うラインをコメントしました。

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

出力:

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 

また、XPathの情報は、Pythonのxml.etree.ElementTreeドキュメント内にもあります。