如何解析XML以获得所需的结果

时间:2015-10-24 14:21:38

标签: python xml automation lxml elementtree

如何解析以下XML以输出 @test:错误消息

XML

<?xml version='1.0' encoding='UTF-8'?>
  <featureResults>
      <feature>
        <comments/>
        <keyword>Feature</keyword>
        <name>Test Feature</name>
        <line>2</line>
        <description></description>
        <tags>
          <Tag>
            <name>@test</name>
            <line>1</line>
          </Tag>
        </tags>
        <id>Test feature</id>
      </feature>
      <uri>Test.feature</uri>
      <scenarioResults>
          <scenario>
            <comments/>
            <keyword>Scenario Outline</keyword>
            <name>Login-logout from Test</name>
            <line>11</line>
            <description></description>
            <tags>
              <Tag>
                <name>@test</name>
                <line>1</line>
              </Tag>
              <Tag>
                <name>@test1</name>
                <line>4</line>
              </Tag>
            </tags>
            <id>Test-feature;login-logout-from-Test;;2</id>
            <type>scenario</type>
          </scenario>
          <steps>
            <StepResult>
              <step>
                <comments/>
                <keyword>Given </keyword>
                <name>navigate to &quot;Hello&quot;</name>
                <line>6</line>
              </step>
              <result>
            <status>failed</status>
            <duration>90475603939</duration>
            <error__message>Error Msg </error__message> 
             </result>
               </scenario>
               </StepResult>
                  </ScenarioResult>

这是我尝试使用lxml元素树的Python脚本,但它在打印失败时给出了空值:

  failures = {}
  doc = etree.parse(os.path.join(Given.xml))
  root = doc.getroot()
  for case in root.findall(".//ScenarioResult"):
     for test in case.findall(".//tags"):
             test.find(".//name").text
             error__message = case.find("error__message")
             if error__message is None:
                    continue
             failures[name] = (error__message.text[:200] + '..') if len(error__message.text) > 200 else error__message.text

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:1)

这应该适用于xml未正确格式化需要找到相对路径

failures = {}
        try:
            doc = etree.parse(os.path.join(resultsDir,detailSummaryFile))
            root = doc.getroot()
            for case in root.findall(".//scenarioResults"):
                name = case.find(".//Tag/name").text
                error__message = case.find(".//error__message")
                if error__message is None:
                    continue
                failures[name] = (error__message.text[:200] + '..') if len(error__message.text) > 200 else error__message.text
            return failures
        except (Exception,IOError), e:
            return  {
                "success": False,
                "error":str(e)
            }

答案 1 :(得分:0)

我认为您可以使用正则表达式过滤xml中的标记并获取所需的内容。我为你写了一些python代码。愿它可以帮到你。

re_a = re.compile('</?\w+.*?>',re.DOTALL)
re_b = re.compile('<\?.*?\?>')
s = re_a.sub('',your_xml) 
s = re_b.sub('',s)
s = re.sub('\\t','',s)
s = re.sub(' ','',s)
s = re.sub('\\n+','\\n',s)
print(s)

结果如下:

Feature
TestFeature
2
@test
1
Testfeature
Test.feature
ScenarioOutline
Login-logoutfromTest
11
@test
1
@test1
4
Test-feature;login-logout-from-Test;;2
scenario
Given
navigateto&quot;Hello&quot;
6
failed
90475603939
ErrorMsg

答案 2 :(得分:0)

It appears that you xml is badly formed.  With fixes:

<?xml version='1.0' encoding='UTF-8'?>
<featureResults>
    <feature>
        <comments/>
        <keyword>Feature</keyword>
        <name>Test Feature</name>
        <line>2</line>
        <description></description>
        <tags>
            <Tag>
                <name>@test</name>
                <line>1</line>
            </Tag>
        </tags>
        <id>Test feature</id>
    </feature>
    <uri>Test.feature</uri>
    <scenarioResults>
        <scenario>
            <comments/>
            <keyword>Scenario Outline</keyword>
            <name>Login-logout from Test</name>
            <line>11</line>
            <description></description>
            <tags>
                <Tag>
                    <name>@test</name>
                    <line>1</line>
                </Tag>
                <Tag>
                    <name>@test1</name>
                    <line>4</line>
                </Tag>
            </tags>
            <id>Test-feature;login-logout-from-Test;;2</id>
            <type>scenario</type>
        </scenario>
        <steps>
            <StepResult>
                <scenario>
                    <step>
                        <comments/>
                        <keyword>Given </keyword>
                        <name>navigate to &quot;Hello&quot;</name>
                        <line>6</line>
                    </step>
                    <result>
                        <status>failed</status>
                        <duration>90475603939</duration>
                        <error__message>Error Msg </error__message>
                    </result>
                </scenario>
            </StepResult>
        </steps>
    </scenarioResults>
    </featureResults>

有一个模块可以将xml转换为字典。 做pip install xmltodict

import xmltodict

with open('1.xml') as fd:
    obj = xmltodict.parse(fd.read())

print(obj['featureResults']['feature']['tags']['Tag']['name'], end=" ")
print(obj['featureResults']['scenarioResults']['steps']['StepResult']['scenario']['result']['error__message'])

@test Error Msg