import dicttoxml
json_req_body = {
"req": {
"SessionKey": "aad3584e-ce40-4937-9eae-5084ab693986",
"ObjectId": "1f79ed70-77c4-ec11-997e-281878c34860",
"PhoneNumber": {
"EntryId": 0,
"CountryCode": "",
"PhoneNumberType": "Home",
"_PhoneNumber": "7073861807",
"_IsPrimary": "true",
"OptOut": "false"
}
}
}
json_to_xml_data = dicttoxml.dicttoxml(json_req_body, attr_type=False,root=False)
#Byte to String
json_to_xml_data = json_to_xml_data.decode("utf-8")
print(json_to_xml_data)
current output:
<req>
<SessionKey>aad3584e-ce40-4937-9eae-5084ab693986</SessionKey>
<ObjectId>1f79ed70-77c4-ec11-997e-281878c34860</ObjectId>
<PhoneNumber>
<EntryId>0</EntryId>
<CountryCode></CountryCode>
<PhoneNumberType>Home</PhoneNumberType>
<_PhoneNumber>7073861807</_PhoneNumber>
<_IsPrimary>true</_IsPrimary>
<OptOut>false</OptOut>
</PhoneNumber>
</req>
I am using dicttoxml package to convert JSON to XML, conversation is happening well. but I have a scenario where JSON keys start with _ . in that scenario need JSON key and values have to be part of the XML parent tag as follows.
expected output;
<req>
<SessionKey>aad3584e-ce40-4937-9eae-5084ab693986</SessionKey>
<ObjectId>1f79ed70-77c4-ec11-997e-281878c34860</ObjectId>
<PhoneNumber PhoneNumber='7073861807' IsPrimary='true'>
<EntryId>0</EntryId>
<CountryCode></CountryCode>
<PhoneNumberType>Home</PhoneNumberType>
<OptOut>false</OptOut>
</PhoneNumber>
</req>
is there a way to achieve this using dicttoxml package, or are there any other packages that support these scenarios?
CodePudding user response:
I don't think dicttoxml
includes such a specific function. However, you can easily make all the changes you want to your xml with ElementTree
:
import dicttoxml
import xml.etree.ElementTree as ET
json_req_body = {
"req": {
"SessionKey": "aad3584e-ce40-4937-9eae-5084ab693986",
"ObjectId": "1f79ed70-77c4-ec11-997e-281878c34860",
"PhoneNumber": {
"EntryId": 0,
"CountryCode": "",
"PhoneNumberType": "Home",
"_PhoneNumber": "7073861807",
"_IsPrimary": "true",
"OptOut": "false"
}
}
}
json_to_xml_data = dicttoxml.dicttoxml(json_req_body, attr_type=False,root=False).decode("utf-8")
elt_tree = ET.XML(json_to_xml_data)
for phone_nb in elt_tree.iter('PhoneNumber'):
remove_children = []
for child in phone_nb:
if child.tag[0] == '_':
phone_nb.set(child.tag.strip('_'), child.text)
remove_children.append(child)
for child in remove_children:
phone_nb.remove(child)
ET.indent(elt_tree)
print(ET.tostring(elt_tree, encoding='unicode'))
Output:
<req>
<SessionKey>aad3584e-ce40-4937-9eae-5084ab693986</SessionKey>
<ObjectId>1f79ed70-77c4-ec11-997e-281878c34860</ObjectId>
<PhoneNumber PhoneNumber="7073861807" IsPrimary="true">
<EntryId>0</EntryId>
<CountryCode />
<PhoneNumberType>Home</PhoneNumberType>
<OptOut>false</OptOut>
</PhoneNumber>
</req>
Edit: for all keys (not only "PhoneNumber") that are directly under root, replace the loop with:
for key_tag in elt_tree:
remove_children = []
for child in key_tag:
if child.tag[0] == '_':
key_tag.set(child.tag.strip('_'), child.text)
remove_children.append(child)
for child in remove_children:
key_tag.remove(child)
(loop over elt_tree.iter()
instead of elt_tree
if you want to process all elements recursively)