1

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>
2
  • key = countrylist[0] does not update your xml. It only creates a new reference/variable key pointing to countrylist[0] Commented Jan 9, 2019 at 13:53
  • @stovfl- how to go about it...can you please suggest it will be of great help Commented Jan 9, 2019 at 15:50

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks it's working now any other alternative for builder or is it inbuilt under lxml?
@Pyjava: " any other alternative for builder or is it inbuilt under lxml": Can't answer this for sure, added the Documentation link to my answer.
What if diction:{'AUSTRALIA': ['MELBOURNE']} ? And I want to keep both the things from dictionary as well as from input xml into output xml? There is a test case failure in that case.
Similar thing in stackoverflow.com/questions/54124953/… .......just that it does not has table_category then how would i update the stringval?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.