1

I need an xpath expression for the following:

All nodes with the tag "test" that have a child with the tag "status" that have an attribute called "status" with the value "PASS"

so with the xml below, I need to get the node with the id "s1-t1". I should be able to modify this so that instead of Passed tests, I get tests with the attribute [@status='FAIL']. I've tried a couple things to no avail:

  • ".//test/[@status='PASS']" returns nothing
  • ".//test/[status][@status='PASS']" returns nothing
  • ".//test//[status][@status='PASS']" throws a SyntaxError("invalid descendant")
  • ".//test//status[@status='PASS']" returns 2 status nodes (one for the test status and one for the keyword status)
  • ".//test//status[@status='PASS']/../.." returns the correct test node, but also the suite node

I'm not sure what to try at this point. Here's the XML I'm working on:

<?xml version="1.0" encoding="UTF-8"?>
<robot generated="20151111 16:29:28.630" generator="Robot 2.9.1 (Python 2.7.10 on cygwin)">
<suite source="/cygdrive/c/test/robot/thing.robot" id="s1" name="Thing">
<test id="s1-t1" name="Case1">
<kw name="Should Contain" library="BuiltIn">
<doc>Fails if ``item1`` does not contain ``item2`` one or more times.</doc>
<arguments>
<arg>hello</arg>
<arg>hell</arg>
</arguments>
<status status="PASS" endtime="20151111 16:29:28.689" starttime="20151111 16:29:28.689"></status>
</kw>
<status status="PASS" endtime="20151111 16:29:28.689" critical="yes" starttime="20151111 16:29:28.688"></status>
</test>
<test id="s1-t2" name="Case2">
<kw name="Should Contain" library="BuiltIn">
<doc>Fails if ``item1`` does not contain ``item2`` one or more times.</doc>
<arguments>
<arg>hello</arg>
<arg>elo</arg>
</arguments>
<msg timestamp="20151111 16:29:28.690" level="FAIL">'hello' does not contain 'elo'</msg>
<status status="FAIL" endtime="20151111 16:29:28.690" starttime="20151111 16:29:28.690"></status>
</kw>
<status status="FAIL" endtime="20151111 16:29:28.690" critical="yes" starttime="20151111 16:29:28.690">'hello' does not contain 'elo'</status>
</test>
<test id="s1-t3" name="Case3">
<kw name="Should Contain" library="BuiltIn">
<doc>Fails if ``item1`` does not contain ``item2`` one or more times.</doc>
<arguments>
<arg>hello</arg>
</arguments>
<msg timestamp="20151111 16:29:28.691" level="FAIL">Keyword 'BuiltIn.Should Contain' expected 2 to 4 arguments, got 1.</msg>
<status status="FAIL" endtime="20151111 16:29:28.691" starttime="20151111 16:29:28.691"></status>
</kw>
<status status="FAIL" endtime="20151111 16:29:28.691" critical="yes" starttime="20151111 16:29:28.691">Keyword 'BuiltIn.Should Contain' expected 2 to 4 arguments, got 1.</status>
</test>
<status status="FAIL" endtime="20151111 16:29:28.692" starttime="20151111 16:29:28.633"></status>
</suite>
<statistics>
<total>
<stat fail="2" pass="1">Critical Tests</stat>
<stat fail="2" pass="1">All Tests</stat>
</total>
<tag>
</tag>
<suite>
<stat fail="2" id="s1" name="Thing" pass="1">Thing</stat>
</suite>
</statistics>
<errors>
</errors>
</robot>

1 Answer 1

1

You are almost there:

.//test[status/@status = "PASS"]

This is exactly All nodes with the tag "test" that have a child with the tag "status" that have an attribute called "status" with the value "PASS".

Sign up to request clarification or add additional context in comments.

8 Comments

SyntaxError("cannot use absolute path on element")
@ewok sure, added the dot.
@ewok is this an xml.etree.ElementTree you are using? It has a rather limited xpath support, switch to lxml.etree if possible.
@ewok I'm afraid that you'll have to loop over the test elements and check if there is a status element with a desired status attribute inside. Lmk if you need an example. Thanks.
nevermind. I was still using root.findall() and I needed to use root.xpath(). thanks!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.