Home > Net >  How to print line number specific element inside complex child elements using python
How to print line number specific element inside complex child elements using python

Time:10-30

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
  • Related