Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Adding attributes with ascending integer values to XML elements only if they have children

I want to add the add attribute ‘id="number"’ to an existing file.
id attributes should only be added if the element has at least one child.
So right now my XML file looks like this:

<Invoice>  
    <Fussteil>
       <Summen>
            <QF/>
            <UstSatz>21.00</UstSatz>
            <Betrag>
                <Bezeichnung>Steuerbetrag</Bezeichnung>
                <QF>124</QF>
                <Wert>8.8</Wert>
            </Betrag>
        </Summen>
        <Betrag>
            <Bezeichnung>Gesamtbetrag alle Zu/Abschläge</Bezeichnung>
            <QF>131</QF>
            <Wert>12.5</Wert>
        </Betrag>
        <Betrag/>
        <Betrag>
            <Bezeichnung>Gesamter Gebuehrenbetrag</Bezeichnung>
            <QF>176</QF>
            <Wert>8.8</Wert>
        </Betrag>
    </Fussteil>  
</Invoice>  

And in the end it should look like this:

<Invoice>  
    <Fussteil id="0">
       <Summen id="1">
            <QF/>
            <UstSatz>21.00</UstSatz>
            <Betrag id="2">
                <Bezeichnung>Steuerbetrag</Bezeichnung>
                <QF>124</QF>
                <Wert>8.8</Wert>
            </Betrag>
        </Summen>
        <Betrag id="3">
            <Bezeichnung>Gesamtbetrag alle Zu/Abschläge</Bezeichnung>
            <QF>131</QF>
            <Wert>12.5</Wert>
        </Betrag>
        <Betrag/>
        <Betrag id="4">
            <Bezeichnung>Gesamter Gebuehrenbetrag</Bezeichnung>
            <QF>176</QF>
            <Wert>8.8</Wert>
        </Betrag>
    </Fussteil>  
</Invoice>  

Have a solution that provides the following output:
So the only thing that is still a problem, is that an id is added to elements that do not have a child.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel


import xml.etree.ElementTree as ET

tree = ET.parse('file.xml')

val = 0

for elem in tree.iter():
    if elem.tag in ["Fussteil", "Summen", "Betrag"]:
        elem.set("id", str(val))
        val += 1 

tree.write('output.xml')


<Invoice>  
    <Fussteil id="0">
       <Summen id="1">
            <QF/>
            <UstSatz>21.00</UstSatz>
            <Betrag id="2">
                <Bezeichnung>Steuerbetrag</Bezeichnung>
                <QF>124</QF>
                <Wert>8.8</Wert>
            </Betrag>
        </Summen>
        <Betrag id="3">
            <Bezeichnung>Gesamtbetrag alle Zu/Abschläge</Bezeichnung>
            <QF>131</QF>
            <Wert>12.5</Wert>
        </Betrag>
        <Betrag id="4" />
        <Betrag id="5">
            <Bezeichnung>Gesamter Gebuehrenbetrag</Bezeichnung>
            <QF>176</QF>
            <Wert>8.8</Wert>
        </Betrag>
    </Fussteil>  
</Invoice> 

>Solution :

Recursion is you friend here:

import xml.etree.ElementTree as ET

xml = '''<Invoice>  
    <Fussteil>
       <Summen>
            <QF/>
            <UstSatz>21.00</UstSatz>
            <Betrag>
                <Bezeichnung>Steuerbetrag</Bezeichnung>
                <QF>124</QF>
                <Wert>8.8</Wert>
            </Betrag>
        </Summen>
        <Betrag>
            <Bezeichnung>Gesamtbetrag alle Zu/Abschläge</Bezeichnung>
            <QF>131</QF>
            <Wert>12.5</Wert>
        </Betrag>
        <Betrag/>
        <Betrag>
            <Bezeichnung>Gesamter Gebuehrenbetrag</Bezeichnung>
            <QF>176</QF>
            <Wert>8.8</Wert>
        </Betrag>
    </Fussteil>  
</Invoice> '''

root = ET.fromstring(xml)

_id = -1


def inc() -> int:
    global _id
    _id += 1
    return _id


def add_id(node: ET.Element) -> None:
    lst = list(node)
    for ele in lst:
        if list(ele):
            ele.attrib['id'] = str(inc())
            add_id(ele)


add_id(root)
ET.dump(root)

output

<Invoice>  
    <Fussteil id="0">
       <Summen id="1">
            <QF />
            <UstSatz>21.00</UstSatz>
            <Betrag id="2">
                <Bezeichnung>Steuerbetrag</Bezeichnung>
                <QF>124</QF>
                <Wert>8.8</Wert>
            </Betrag>
        </Summen>
        <Betrag id="3">
            <Bezeichnung>Gesamtbetrag alle Zu/Abschläge</Bezeichnung>
            <QF>131</QF>
            <Wert>12.5</Wert>
        </Betrag>
        <Betrag />
        <Betrag id="4">
            <Bezeichnung>Gesamter Gebuehrenbetrag</Bezeichnung>
            <QF>176</QF>
            <Wert>8.8</Wert>
        </Betrag>
    </Fussteil>  
</Invoice>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading