How to print line number specific element inside complex child elements using python
Question:
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.
Answers:
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
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.
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