peizidiao
peizidiao

Reputation: 15

Use xpath to locate nodes through two attributes in python

I want to use Xpath to locate certain node through two attributes. This is an example:

from xml.etree import ElementTree as ET

xmldata="""
<postlinks>
  <row Id="19" CreationDate="2010-04-26T02:59:48.130" PostId="109" RelatedPostId="32412" LinkTypeId="1" />
  <row Id="37" CreationDate="2010-04-26T02:59:48.600" PostId="1970" RelatedPostId="617600" LinkTypeId="1" />
  <row Id="42" CreationDate="2010-04-26T02:59:48.647" PostId="2154" RelatedPostId="2451138" LinkTypeId="1" />
</postlinks>
"""
import io
tree = ET.parse(io.StringIO(xmldata))
nodes = tree.find(".//row[@PostId='109' and @RelatedPostId='32412']")
print(nodes.attrib)

I want to locate the node with Id='19' through PostId='109' and RelatedPostId='32412'.

But i get this error:

Traceback (most recent call last):
  File "D:\anaconda\envs\PRTagRec\lib\xml\etree\ElementPath.py", line 272, in iterfind
    selector = _cache[cache_key]
KeyError: (".//row[@PostId='109' and @RelatedPostId='32412']", None)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "D:/pythonProject/LabelLink/temp.py", line 20, in <module>
    nodes = tree.find(".//row[@PostId='109' and @RelatedPostId='32412']")
  File "D:\anaconda\envs\PRTagRec\lib\xml\etree\ElementTree.py", line 653, in find
    return self._root.find(path, namespaces)
  File "D:\anaconda\envs\PRTagRec\lib\xml\etree\ElementPath.py", line 307, in find
    return next(iterfind(elem, path, namespaces), None)
  File "D:\anaconda\envs\PRTagRec\lib\xml\etree\ElementPath.py", line 286, in iterfind
    selector.append(ops[token[0]](next, token))
  File "D:\anaconda\envs\PRTagRec\lib\xml\etree\ElementPath.py", line 242, in prepare_predicate
    raise SyntaxError("invalid predicate")
SyntaxError: invalid predicate

But when I use one attribute, such as nodes = tree.find(".//row[@PostId='109']") or nodes = tree.find(".//row[@RelatedPostId='32412']"), I get that node. {'Id': '19', 'CreationDate': '2010-04-26T02:59:48.130', 'PostId': '109', 'RelatedPostId': '32412', 'LinkTypeId': '1'}

How should I do?

Upvotes: 0

Views: 49

Answers (1)

Aaron
Aaron

Reputation: 1368

Append the predicate to make a logical AND.

from xml.etree import ElementTree as ET

xmldata="""
<postlinks>
  <row Id="19" CreationDate="2010-04-26T02:59:48.130" PostId="109" RelatedPostId="32412" LinkTypeId="1" />
  <row Id="37" CreationDate="2010-04-26T02:59:48.600" PostId="1970" RelatedPostId="617600" LinkTypeId="1" />
  <row Id="42" CreationDate="2010-04-26T02:59:48.647" PostId="2154" RelatedPostId="2451138" LinkTypeId="1" />
</postlinks>
"""
import io
tree = ET.parse(io.StringIO(xmldata))
nodes = tree.find(".//row[@PostId='109'][@RelatedPostId='32412']")
print(nodes.attrib)

Upvotes: 1

Related Questions