使用python函数进行Xml解析并创建制表符间隔关系数据

时间:2016-05-10 05:56:01

标签: python xml function parsing

尝试解析由squish生成的xml并以tsv格式创建关系数据以将其上载到数据库。 Xml看起来像

<SquishReport version="2.2" xmlns="http://www.froglogic.com/XML2">
<test name="ATF_Sandbox">
    <prolog time="2016-05-05T06:43:43+05:30"/>
    <test name="tst_MapView">
        <prolog time="2016-05-05T06:43:43+05:30"/>
        <message line="30" type="LOG" file="D:\TestSlave5\workspace\TestSlave5 SyncCode\SquishTests\ATF_Sandbox\tst_MapView\test.py" time="2016-05-05T06:44:41+05:30">
            <description><![CDATA[CS.VPR.MAP.VSL.MPV.001]]></description>
        </message>
        <verification line="759" type="" name="" file="D:\TestSlave5\workspace\TestSlave5 SyncCode\SquishTests\suite_common\squishFunctions.py">
            <result type="PASS" time="2016-05-05T06:44:51+05:30">
                <description>Check: Current map mode is 'Overview' mode</description>
                <description type="DETAILED"></description>
            </result>
        </verification>
        <verification line="2264" type="" name="" file="D:\TestSlave5\workspace\TestSlave5 SyncCode\SquishTests\suite_common\squishFunctions.py">
            <result type="PASS" time="2016-05-05T06:44:52+05:30">
                <description>Teststep: CS.VPR.MAP.VSL.MPV.001 (Screenshot in "D:/TestSlave5/workspace/TestSlave5 SyncCode/SquishTests/ATF_Sandbox/tst_MapView\failedImages\failed_46.png")</description>
                <description type="DETAILED">Screen shot captured: #REMARK MANUAL VERIFICATION REQUIRED STEP: &lt;ccp is pointing north up></description>
                <description type="file">D:/TestSlave5/workspace/TestSlave5 SyncCode/SquishTests/ATF_Sandbox/tst_MapView\failedImages\failed_46.png</description>
            </result>
        </verification>
        <message line="48" type="LOG" file="D:\TestSlave5\workspace\TestSlave5 SyncCode\SquishTests\ATF_Sandbox\tst_MapView\test.py" time="2016-05-05T06:44:52+05:30">
            <description><![CDATA[CS.VPR.MAP.VSL.MPV.002]]></description>
        </message>
        <verification line="2264" type="" name="" file="D:\TestSlave5\workspace\TestSlave5 SyncCode\SquishTests\suite_common\squishFunctions.py">
            <result type="PASS" time="2016-05-05T06:44:52+05:30">
                <description>Teststep: CS.VPR.MAP.VSL.MPV.002 (Screenshot in "D:/TestSlave5/workspace/TestSlave5 SyncCode/SquishTests/ATF_Sandbox/tst_MapView\failedImages\failed_47.png")</description>
                <description type="DETAILED">Screen shot captured: #REMARK WORKAROUND FOR : &lt;resolution of the screen is 400x240> &lt;Verifying width and height of the HomeScreen></description>
                <description type="file">D:/TestSlave5/workspace/TestSlave5 SyncCode/SquishTests/ATF_Sandbox/tst_MapView\failedImages\failed_47.png</description>
            </result>
        </verification>
        <verification line="61" type="" name="" file="D:\TestSlave5\workspace\TestSlave5 SyncCode\SquishTests\ATF_Sandbox\tst_MapView\test.py">
            <result type="PASS" time="2016-05-05T06:44:52+05:30">
                <description>Comparison</description>
                <description type="DETAILED">'400' and '400' are equal</description>
            </result>
        </verification>
        <message line="71" type="LOG" file="D:\TestSlave5\workspace\TestSlave5 SyncCode\SquishTests\ATF_Sandbox\tst_MapView\test.py" time="2016-05-05T06:44:52+05:30">
            <description><![CDATA[CS.VPR.MAP.VSL.MPV.003]]></description>
        </message>
        <verification line="2264" type="" name="" file="D:\TestSlave5\workspace\TestSlave5 SyncCode\SquishTests\suite_common\squishFunctions.py">
            <result type="PASS" time="2016-05-05T06:44:53+05:30">
                <description>Teststep: CS.VPR.MAP.VSL.MPV.003 (Screenshot in "D:/TestSlave5/workspace/TestSlave5 SyncCode/SquishTests/ATF_Sandbox/tst_MapView\failedImages\failed_48.png")</description>
                <description type="DETAILED">Screen shot captured: #REMARK MANUAL VERIFICATION REQUIRED STEP: &lt;Map is centered at center of map.></description>
                <description type="file">D:/TestSlave5/workspace/TestSlave5 SyncCode/SquishTests/ATF_Sandbox/tst_MapView\failedImages\failed_48.png</description>
            </result>
        </verification>
        <message line="356" type="LOG" file="D:\TestSlave5\workspace\TestSlave5 SyncCode\SquishTests\ATF_Sandbox\tst_MapView\test.py" time="2016-05-05T06:48:22+05:30">
            <description><![CDATA[CS.VPR.MAP.VSL.RDM.003]]></description>
        </message>
        <message line="365" type="LOG" file="D:\TestSlave5\workspace\TestSlave5 SyncCode\SquishTests\ATF_Sandbox\tst_MapView\test.py" time="2016-05-05T06:48:22+05:30">
            <description><![CDATA[#REMARK MANUAL VERIFICATION REQUIRED STEP: <Route preview is played at 300% of normal road speed>]]></description>
        </message>
        <message line="370" type="LOG" file="D:\TestSlave5\workspace\TestSlave5 SyncCode\SquishTests\ATF_Sandbox\tst_MapView\test.py" time="2016-05-05T06:48:22+05:30">
            <description><![CDATA[CS.VPR.MAP.VSL.RDM.004]]></description>
        </message>
        <message line="379" type="LOG" file="D:\TestSlave5\workspace\TestSlave5 SyncCode\SquishTests\ATF_Sandbox\tst_MapView\test.py" time="2016-05-05T06:48:22+05:30">
            <description><![CDATA[#REMARK MANUAL VERIFICATION REQUIRED STEP: <Route Preview starts playing from the beginning and keeps looping until the Route Preview is stopped>]]></description>
        </message>
        <message line="384" type="LOG" file="D:\TestSlave5\workspace\TestSlave5 SyncCode\SquishTests\ATF_Sandbox\tst_MapView\test.py" time="2016-05-05T06:48:22+05:30">
            <description><![CDATA[CS.VPR.MAP.VSL.RDM.005]]></description>
        </message>
        <verification line="102" type="" name="" file="D:\TestSlave5\workspace\TestSlave5 SyncCode\SquishTests\suite_common\squishFunctions.py">
            <result type="PASS" time="2016-05-05T06:48:22+05:30">
                <description>Comparison</description>
                <description type="DETAILED">'True' and 'True' are equal</description>
                <description type="DETAILED">Check if existence of widget ':HomeView.btnToggleMap_CMapTogglePushButton' equals True</description>
            </result>
        </verification>
        <verification line="102" type="" name="" file="D:\TestSlave5\workspace\TestSlave5 SyncCode\SquishTests\suite_common\squishFunctions.py">
            <result type="PASS" time="2016-05-05T06:48:22+05:30">
                <description>Comparison</description>
                <description type="DETAILED">'True' and 'True' are equal</description>
                <description type="DETAILED">Check if existence of widget ':HomeView.btnZoomIn_QPushButton' equals True</description>
            </result>
        </verification>

我试图以关系格式实现数据,看起来像 -

CS.VPR.MAP.VSL.MPV.001  PASS    Check: Current map mode is 'Overview' mode  None    None
CS.VPR.MAP.VSL.MPV.001  PASS    Teststep: CS.VPR.MAP.VSL.MPV.001 (Screenshot in "D:/TestSlave5/workspace/TestSlave5 SyncCode/SquishTests/ATF_Sandbox/tst_MapView\failedImages\failed_46.png")   Screen shot captured: #REMARK MANUAL VERIFICATION REQUIRED STEP: <ccp is pointing north up>     MANUAL
CS.VPR.MAP.VSL.MPV.002  PASS    Teststep: CS.VPR.MAP.VSL.MPV.002 (Screenshot in "D:/TestSlave5/workspace/TestSlave5 SyncCode/SquishTests/ATF_Sandbox/tst_MapView\failedImages\failed_47.png")   Screen shot captured: #REMARK WORKAROUND FOR : <resolution of the screen is 400x240> <Verifying width and height of the HomeScreen>     None
CS.VPR.MAP.VSL.RDM.003  PASS    #REMARK MANUAL VERIFICATION REQUIRED STEP: <Route preview is played at 300% of normal road speed>   None 
CS.VPR.MAP.VSL.RDM.004  PASS    #REMARK MANUAL VERIFICATION REQUIRED STEP: <Route Preview starts playing from the beginning and keeps looping until the Route Preview is stopped>   None 

我可以通过以下脚本实现这一目标 -

for test in root.getchildren():
for test2 in test.getchildren():
    for message in test2.getchildren():
        if message.tag == "{http://www.froglogic.com/XML2}message":
            messageText1 = message[0].text
            if re.match(testStepPattern, messageText1):
                testStepID = messageText1
            elif messageText1.startswith('#REMARK MANUAL'):
                remarkTag = message[0].text
                print testStepID, '\t', 'PASS', '\t', remarkTag, '\t', "None", '\t', "NOT AUTOMATED"
        elif message.tag == "{http://www.froglogic.com/XML2}verification":
            resultAttrib = message[0].attrib.get('type')
            resultDetails = message[0][0].text
            resultDetailsMore = message[0][1].text
            if "REMARK MANUAL" in str(resultDetailsMore):
                print testStepID, '\t', resultAttrib, '\t', resultDetails, '\t', resultDetailsMore, '\t', "MANUAL"
            else:
                print testStepID, '\t', resultAttrib, '\t', resultDetails, '\t', resultDetailsMore, '\t', "None"

但是当尝试将此脚本拆分为函数时,它会抛出错误

Traceback (most recent call last):
File "parser.py", line 85, in <module>
   ParseXmlResults()
File "parser.py", line 56, in ParseXmlResults
testStepID, remarkTag = CheckAndGetMessageTagValues(message)
TypeError: 'NoneType' object is not iterable

以下是拆分代码 -

import xml.etree.ElementTree as ET
import re

tree = ET.parse(r"C:\Users\M1032828\Desktop\result_MapView.xml")
root = tree.getroot()
testSetTree = root[0][1]

testStepPattern = re.compile(r"\b([A-Z]{2,4}\.){4,5}[\d]{2,}\b")
testStepID = ""
tagDetails = ""


def ParseXmlResults_ESR():
    global testStepID
    for test in root.getchildren():
        print test
        for test2 in test.getchildren():
            print "--------------------------------->", test2
            for message in test2.getchildren():
                print '***********************>', message
                if message.tag == "{http://www.froglogic.com/XML2}message":
                    messageText1 = message[0].text
                    print messageText1
                    testStepID, remarkTag = CheckAndGetMessageTagValues(message)
                    print testStepID, remarkTag
                elif message.tag == "{http://www.froglogic.com/XML2}verification":
                    resultAttrib, resultDetails, resultDetailsMore = CheckAndGetVerificationTagDetails(message)
                    print resultAttrib, resultDetails, resultDetailsMore

def CheckAndGetMessageTagValues(element):
    global testStepID
    global tagDetails
    if re.match(testStepPattern, element[0].text):
        testStepID = element[0].text
        tagDetails = False
        remarkTag = ""
        return testStepID, remarkTag
    elif element[0].text.startswith('#REMARK MANUAL'):
        tagDetails = True
        remarkTag = element[0].text
        return testStepID, remarkTag


def CheckAndGetVerificationTagDetails(element):
    resultAttrib = element[0].attrib.get('type')
    resultDetails = element[0][0].text
    resultDetailsMore = element[0][1].text
    return resultAttrib, resultDetails, resultDetailsMore

if __name__ == "__main__":
    ParseXmlResults()

有人可以帮我解决这个问题。提前致谢

1 个答案:

答案 0 :(得分:0)

您收到此错误的原因是CheckAndGetMessageTagValues没有返回任何内容,因为您的测试:re.match(testStepPattern, element[0].text)element[0].text.startswith('#REMARK MANUAL')都没有返回True,因此它没有运行任何if子句。

你应该做的是确保其中一个测试总是返回True,或者更好,添加一个else子句,它会返回默认值(或者甚至可能更好地引发异常,如果情况是意外的话)没有人其他条件已经满足。

def CheckAndGetMessageTagValues(element):
    global testStepID
    global tagDetails
    if re.match(testStepPattern, element[0].text):
        testStepID = element[0].text
        tagDetails = False
        remarkTag = ""
        return testStepID, remarkTag
    elif element[0].text.startswith('#REMARK MANUAL'):
        tagDetails = True
        remarkTag = element[0].text
        return testStepID, remarkTag
    else:
        return "defaultID", "noTagFound"
        # or raise an Exception?