1

My XML file looks something like this:

<SCAN_LIST_OUTPUT>
  <RESPONSE>
    <DATETIME>2018-05-21T11:29:05Z</DATETIME>
    <SCAN_LIST>
      <SCAN>
        <REF>scan/1526727908.25005</REF>
        <TITLE><![CDATA[ACRS_Scan]]></TITLE>
        <LAUNCH_DATETIME>2018-05-19T11:05:08Z</LAUNCH_DATETIME>
      </SCAN>
      <SCAN>
        <REF>scan/1526549903.07613</REF>
        <TITLE><![CDATA[testScan]]></TITLE>
        <LAUNCH_DATETIME>2018-05-17T09:38:23Z</LAUNCH_DATETIME>
      </SCAN>
    </SCAN_LIST>
  </RESPONSE>
</SCAN_LIST_OUTPUT>

Now when I try to find the REF element of the first element using an absolute path where I know the LAUNCH_DATETIME it gives me an error saying invalid predicate. Here is my code:

import xml.etree.ElementTree as ET

tree = ET.ElementTree(ET.fromstring(response))
groot = tree.getroot()
path = './/REF[../LAUNCH_DATETIME="2018-05-19T11:05:08Z"]'
scan_id = tree.find(path)

Here is the following traceback call:

KeyError: ('.//REF[../LAUNCH_DATETIME="2018-05-19T11:05:08Z"]', None)

During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/home/doomsday/PycharmProjects/untitled/venv/ScanList.py", line 44, in <module>
    scan_id = tree.find(path)
  File "/usr/lib/python3.5/xml/etree/ElementTree.py", line 651, in find
    return self._root.find(path, namespaces)
  File "/usr/lib/python3.5/xml/etree/ElementPath.py", line 298, in find
    return next(iterfind(elem, path, namespaces), None)
  File "/usr/lib/python3.5/xml/etree/ElementPath.py", line 277, in iterfind
    selector.append(ops[token[0]](next, token))
  File "/usr/lib/python3.5/xml/etree/ElementPath.py", line 233, in prepare_predicate
    raise SyntaxError("invalid predicate")
SyntaxError: invalid predicate

When I use the same absolute path on an online xpath evaluator, it gives me the desired output. But when I try the same in my code, it fails. If anyone could tell what the problem is and how it can be resolved, would be great.

Thanks in advance.

5
  • What are you actually trying to achieve? Commented May 21, 2018 at 12:50
  • @zipa I am trying to locate the <REF> child of the first <SCAN> element using the absolute path I provided above with the <LAUNCH_DATETIME> child value known to me.... Commented May 21, 2018 at 12:55
  • 1
    @DevanshuMisra i don't think that is possible. I would retrieve the full <scan> element and then handle and evaluate the child values Commented May 21, 2018 at 12:58
  • 1
    @DevanshuMisra maybe this is what you are looking for link Commented May 21, 2018 at 13:01
  • @Bonzay Yes sir, it isnt. As i read the answer provided below, I had to retrieve the <SCAN> element for working around it and then fetch the required element. Commented May 22, 2018 at 5:58

1 Answer 1

1

ElementTree's xpath support is limited. Instead of trying to go back up the tree with .. in a predicate on REF, add the predicate to SCAN.

Example...

path = './/SCAN[LAUNCH_DATETIME="2018-05-19T11:05:08Z"]/REF'
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you sir, this totally worked. Now I understand how the predicate mattered, Moreover, I really did not know about the xpath support provided by ElementTree. Thanks again for helping me out
@DevanshuMisra - you’re very welcome. If you need to use more complicated xpaths, consider using lxml instead.
Sure sir. But as far as my understanding goes, Elementtree comes in stdlib but lxml can be an external dependency. And this code is just a snippet of an application that i'm writing which will then be sent on different machines. And(I'm not too sure about this), external dependencies should be kept to a bare minimum I suppose

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.