簡體   English   中英

Python XML按順序解析子標簽

[英]Python XML Parsing the child tags in order

我的XML文件類似於以下文件:

<suite name="regression_1">
    <test name="Login check" id="s1-t1">
        <keyword name="Valid Username and Password">
            <keyword name="Invalid Username or Password">
                <keyword name="Invalid password">
                    <message level="TRACE" >Return error</message>
                    <status status="PASS"/>
                </keyword>
                <message level="INFO">Return error</message>
                <status status="FAIL"/>
            </keyword>
            <message level="INFO">Return: None</message>
            <status status="PASS"/>
        </keyword>
        <status status="FAIL"/>
    </test>
    <test name="test-2" id="s1-t1">
        <keyword name="abc">
            <keyword name="def">
                <message level="INFO">Return error</message>
                <status status="FAIL"/>
            </keyword>
            <message level="INFO">Return: None</message>
            <status status="PASS"/>
        </keyword>
        <status status="FAIL"/>
    </test>
</suite>

我的輸出應檢查關鍵字,並為狀態為“失敗”的關鍵字提供關鍵字結構。 一個測試中將有許多關鍵字,並且可能有或沒有子關鍵字。

****樣本輸出*******

套件:regress_1

測試名稱:登錄檢查

關鍵字失敗:[“有效的用戶名和密碼”,“無效的用戶名或密碼”]

失敗測試案例消息:返回錯誤

套件:regress_1

測試名稱:test-2

關鍵字失敗:[“ abc”,“ def”]

失敗測試案例消息:返回錯誤


我的代碼能夠挖掘到最后一個孩子,以收集失敗狀態。 但是無法解析分析所需的正確路徑。 我也認為完整的循環沒有得到執行。 例如,如果第三個孩子是“ PASS”,則它不會返回第二個孩子來檢查其狀態。

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


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

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

top = Element('tests')
comment = Comment("This xml is generated only for failing tests")
top.append(comment)


for tc in tc_entry:
    if tc.hasAttribute("name"):
       print("Suite name: {}".format(tc.getAttribute("name")))

    tests = tc.getElementsByTagName('test')
    for test in tests:
        keyword_track = []
        for child in test.childNodes:
            if child.nodeName == "keyword":
                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("Keyword failed: {}".format(tc_name.getAttribute("name")))
                            print("Status: {}".format(state.getAttribute("status")))
                            messages = tc_name.getElementsByTagName('msg')
                            print("Failure test case messages:")
                            for message in messages:
                                print(message.childNodes[0].data)
                            print ("")

從此代碼收到的輸出:

測試名稱:ABC

關鍵字名稱:keyword_1-2-3

狀態:失敗

失敗測試案例消息:在級別3中失敗

對代碼有任何建議的優化嗎?

問題 :XML按順序解析子標記

例如,使用xml.etree.ElementTree解決方案:

注意 :讓<keyword>的第一個<keyword> Keyword faild:仍然沒有意義Keyword faild:都具有PASS 如果要在輸出中包含第一個<keyword> ,請刪除#

from xml.etree import ElementTree as ET

with open('output.xml') as fh:
    suite = ET.fromstring(fh.read())

# Find all <test>"
for test in suite.findall('./test'):
    keyword_failed = []
    # first_keyword = test.find('./keyword')
    # keyword_failed = [first_keyword.attrib['name']]
    message = None

    # Find all <test><keyword> <status status="FAIL">
    for keyword in test.findall('.//keyword/status[@status="FAIL"]/..'):
        keyword_failed.append(keyword.attrib['name'])
        message = keyword.find('./message')

        print('Suite: {}'.format(suite.attrib['name']))
        print('\tTest Name: {}'.format(test.attrib['name']))
        print('\tKeyword failed: {}'.format(keyword_failed))
        print('\tFailure test case message : level={} {}'.format(message.attrib['level'], message.text))

輸出
套件:regress_1
測試名稱:登錄檢查
關鍵字失敗:['無效的用戶名或密碼']
失敗測試案例消息:level = INFO返回錯誤
套件:regress_1
測試名稱:test-2
關鍵字失敗:['def']
失敗測試案例消息:level = INFO返回錯誤

使用Python測試:3.4.2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM