Python - How to append the same XML element multiple times with lxml.objectify

I have the following XML that I am trying to recreate with the lxml.objectify package

<file>
  <customers>
    <customer>
        <phone>
            <type>home</type>
            <number>555-555-5555</number>
        </phone>
        <phone>
            <type>cell</type>
            <number>999-999-9999</number>
        </phone>
        <phone>
            <type>home</type>
            <number>111-111-1111</number>
        </phone>
    </customer>
   </customers>
</file>

I can't figure out how to create the phone element multiple times. Basically, I have the following non-working code:

    # create phone element 1
    root.customers.customer.phone = ""
    root.customers.customer.phone.type = data_dict['PRIMARY PHONE1']
    root.customers.customer.phone.number = data_dict['PRIMARY PHONE TYPE 1']

    # create phone element 2
    root.customers.customer.phone = ""
    root.customers.customer.phone.type = data_dict['PRIMARY PHONE2']
    root.customers.customer.phone.number = data_dict['PRIMARY PHONE TYPE 2']

    # create phone element 3
    root.customers.customer.phone = ""
    root.customers.customer.phone.type = data_dict['PRIMARY PHONE3']
    root.customers.customer.phone.number = data_dict['PRIMARY PHONE TYPE 3']

Which of course only outputs one section of phone information in the resulting XML. Does anyone have any ideas?

Answers


You should create objectify.Element objects, and add them as children of root.customers.

For example, inserting two phone numbers can be done like this:

phone = objectify.Element('phone')
phone.type = data_dict['PRIMARY PHONE1']
phone.number = data_dict['PRIMARY PHONE TYPE 1']
root.customers.customer.append(phone)

phone = objectify.Element('phone')
phone.type = data_dict['PRIMARY PHONE2']
phone.number = data_dict['PRIMARY PHONE TYPE 2']
root.customers.customer.append(phone)

If you get unnecessary attributes on these elements when transforming the xml back to a string, use objectify.deannotate(root, xsi_nil=True, cleanup_namespaces=True). See lxml's objectify documentation for exact parameters of objectify.deannotate.

(If you're using an older version of lxml, which doesn't include the cleanup_namespaces keyword argument, do this instead:

from lxml import etree
# ...
objectify.deannotate(root, xsi_nil=True)
etree.cleanup_namespaces(root)

)


Here's some sample code that constructs XML with the objectify E-Factory:

from lxml import etree
from lxml import objectify

E = objectify.E

fileElem = E.file(
    E.customers(
        E.customer(
            E.phone(
                E.type('home'),
                E.number('555-555-5555')
            ),
            E.phone(
                E.type('cell'),
                E.number('999-999-9999')
            ),
            E.phone(
                E.type('home'),
                E.number('111-111-1111')
            )
        )
    )
)

print(etree.tostring(fileElem, pretty_print=True))

I've hardcoded it here but you can convert to a loop over your data. Does that work for your purposes?


Need Your Help

Android Getting Runtime Error While Starting App

java android xml android-intent runtime-error

I'm trying to launch my app but i'm getting runtime error all the time.

Wordpress wp_query instead of

wordpress

I have this function that displays the 5 most viewed posts.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.