问题
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