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.

Asked By: Anonymous

||

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
Answered By: LMC
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.