My python function to get the attribute value of an element
import lxml.etree as ET
def xml_get_attrib_value(filepath, xpath, attribute):
it = ET.iterparse(filepath)
for _, el in it:
_, _, el.tag = el.tag.rpartition('}')
root = it.root
element = root.find(xpath)
value = element.attrib[attribute]
return value
Snippet of XML:
<outboundRelationship typeCode="SPRT">
<priorityNumber value="1" />
<relatedInvestigation classCode="INVSTG" moodCode="EVN">
<code code="2" codeSystem="2.16.840.1.113883.3.989.2.1.1.22" codeSystemVersion="2.0" />
I want to get the value of attribute, 'value' in <priorityNumber value="1" />
If I send an xpath that is straightforward, it works.
xpath: .//outboundRelationship[@typeCode='SPRT']/priorityNumber
However, if I want to check for the attribute of PriorityNumber with a condition that it should be a sibling of ‘relatedInvestigation’ which in turn has a child node, ‘code’ with specific attribute. I get error ‘SyntaxError: invalid predicate
’
xpath: .//outboundRelationship[@typeCode='SPRT'][relatedInvestigation/code[@code='2'][@codeSystem='2.16.840.1.113883.3.989.2.1.1.22']]/priorityNumber
I tried using preceding:sibling in the xpath but that’s also not working.
How to send such xpath? Is there any other way of doing this?
OP's xpath expression is correct but find()
method has limited xpath support. See also FAQ.
Using xpath()
instead of find()
with same expression:
from lxml import etree
xtree = etree.parse('tmp.xml')
p = xtree.xpath(".//outboundRelationship[@typeCode='SPRT'][relatedInvestigation/code[@code='2'][@codeSystem='2.16.840.1.113883.3.989.2.1.1.22']]/priorityNumber")
print(p[0].attrib['value'])
Result
'1'
lxml version
etree.__version__
'4.9.3'
If namespaces are needed
ns = {'ns' : 'urn:hl7-org:v3'}
p = xtree.xpath(".//ns:outboundRelationship[@typeCode='SPRT'][ns:relatedInvestigation/ns:code[@code='2'][@codeSystem='2.16.840.1.113883.3.989.2.1.1.22']]/ns:priorityNumber",namespaces=ns)