Pyjava
Pyjava

Reputation: 117

How to update existing xml element with new given element using python?

I have input XML as country.xml:-

<root>
<set>
    <name>Countries</name>
    <elements>
    <name>US</name>
    <city>
        <val>New York</val>
        <val>Las Vegas</val>
    </city>
    </elements>
    <elements>
    <name>UK</name>
    <city>
        <val>London</val>
    </city>
    </elements>
</set>
</root>

I am parsing xml and taking it into a list and i have a dictionary based on which I am comparing and adding xml elements.

diction: dict = {'US':['New York', 'Chicago'], 'UK':['OXFORD', 'London']}
source = etree.getroot()
for key,value in diction.items()
    countrylist = source.xpath('./elements/name[text()=\'{}\']/..'.format(key))
    if len(countrylist) == 0:
        # creating new string and element
        # appending element to original tree
    elif len(countrylist) == 1:   ###This is problematic case what to expect here to update key,value from dictionary only and replace the tag already present in xml
        key = countrylist[0]
    else:
        countinue

    # writebacktoxml(source,"country.xml")

Output I am getting is original input condition as it is in output for specific condition. Expected output is below:-

<root>
<set>
    <name>Countries</name>
    <elements>
    <name>US</name>
    <city>
        <val>New York</val>
        <val>Chicago</val>
    </city>
    </elements>
    <elements>
    <name>UK</name>
    <city>
        <val>OXFORD</val>
        <val>London</val>
    </city>
    </elements>
</set>
</root>

Upvotes: 1

Views: 648

Answers (1)

stovfl
stovfl

Reputation: 15533

Comment: What if diction:{'AUSTRALIA': ['MELBOURNE']} ? And I want to keep both the things from dictionary as well as from input xml into output xml?

  • Add a condition around .clear

    if name.text in ['AUSTRALIA']:
        # Keep the values
        pass
    else:
        table_category.clear()
    

Question: How to update existing xml element with new given <val>...</val>?

Documentation: The lxml.etree Tutorial - The E-factory
Python Documentation -The ElementTree XML API - Modifying an XML File


  • Example using lxml

    from lxml import etree
    from lxml.builder import ElementMaker
    
  • Data dict

    diction = {'US': ['New York', 'Chicago'], 'UK': ['OXFORD', 'London']}
    
  • Instantiate a ElementMaker object and a new <val>...</val> object.

    E = ElementMaker()
    VAL = E.val
    
  • Parse the source xml

    tree = etree.parse(io.StringIO(xmlf))
    root = tree.getroot()
    
  • Parse all set/elements

    for element in root.findall('set/elements'):
    
  • Get the name of this element

        name = element.find('name')
    
  • Get the table_category of this element and .clear it

        table_category = element.find('table_category')
        table_category.clear()
    
  • Loop all items from the list in diction defined for [name.text].

        for val in diction[name.text]:
    
  • Append a new <val>val</val> to table_category

            table_category.append(VAL(val))
    

Output: print('{}'.format(etree.tostring(root, pretty_print=True).decode()))

<configroot version="8.0">
<set>
    <name>Countries</name>
    <elements>
    <name>US</name>
    <table_category><val>New York</val><val>Chicago</val></table_category></elements>
    <elements>
    <name>UK</name>
    <table_category><val>OXFORD</val><val>London</val></table_category></elements>
</set>
</configroot>

Tested with Python: 3.5

Upvotes: 1

Related Questions