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

冷暖自知 提交于 2019-12-13 06:07:04

问题


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?


回答1:


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)

)




回答2:


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?



来源:https://stackoverflow.com/questions/12324128/python-how-to-append-the-same-xml-element-multiple-times-with-lxml-objectify

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!