Example of my XML1 consists of format of Equal element :
<Operator>
<Equal>
<Data>A1</Data>
<Data>2</Data>
</Equal>
<Equal>
<Integer>A2</Integer>
<Data>2</Data>
</Equal>
<Equal>
<Integer>A3</Integer>
<Integer>2</Integer>
</Equal>
</Operator>
And the following code runs fine for finding 'equal' elements if there are not many child element
doc = etree.parse('C:/Python/Sample.xml')
doc2 = etree.parse('C:/Python/Project.xml')
values = [e.xpath('.//*[2]')[0].text for e in doc.xpath('.//Equal')]
for service in doc2.xpath('//Sub_Function_1//Data[Label and .//Equal//*[2]]'):
value = service.xpath('.//Equal//*[2]')
if value[0].text in values:
print(service.xpath('.//Label/text()')[0], f"lineno: {value[0].sourceline}")
small example of XML2 is as follows where its not able to match 'equal' in all cases :
<File>
<Sub_Function_1>
<Messages>
<Setting>
<Data>
<Label>Setting_1</Label>
<Bit_count>8</Bit_count>
<Value>
<Default_value_if_undefined>
<Value>
<!---->
<Value_on_boolean>
<And>
<Equal>
<Integer>area_1</Integer>
<Data>2</Data>
</Equal>
</And>
</Value_on_boolean>
</Value>
<Default_value>
<Integer>0</Integer>
</Default_value>
</Default_value_if_undefined>
</Value>
</Data>
<Data>
<Label>Setting_2</Label>
<Bit_count>1</Bit_count>
<Value>
<Value_on_condition>
<Case>
<Value>
<Integer>1</Integer>
</Value>
<Condition>
<And>
<Equal>
<Integer>0</Integer>
<Integer>0</Integer>
</Equal>
<Equal>
<Data>area_2</Data>
<Integer>0</Integer>
</Equal>
</And>
</Condition>
</Case>
<Case>
<Value>
<Integer>2</Integer>
</Value>
<Condition>
<And>
<Equal>
<Data>area_3</Data>
<Integer>1</Integer>
</Equal>
<Equal>
<Integer>area_4</Integer>
<Data>0</Data>
</Equal>
</And>
</Condition>
</Case>
<Case>
<Value>
<Integer>3</Integer>
</Value>
<Condition/>
</Case>
</Value_on_condition>
</Value>
</Data>
</Setting>
</Messages>
</Sub_Function_1>
</File>
Running the above code give results as:
Setting_1 lineno: 18
But its not able to find 'equal' inside 'value on condition' as there are many cases inside it so line number 39 and 60 its not printing
Always grateful for any help.
CodePudding user response:
The code is taking only the first Equal
found so it fails when there are 2 or more
for service in doc.xpath('//Sub_Function_1//Data[Label and .//Equal[(*[1][self::Data] and *[2][self::Data]) or *[1][self::Integer]]]'):
eqs = service.xpath('.//Equal[(*[1][self::Data] and *[2][self::Data]) or *[1][self::Integer]]/*[2]')
for e in eqs:
print(service.xpath('.//Label/text()')[0], f"lineno: {e.sourceline}")
Result
Setting_1 lineno: 16
Setting_2 lineno: 40
Setting_2 lineno: 61