Home > Mobile >  JSON to XML conversion with python (dicttoxml)
JSON to XML conversion with python (dicttoxml)

Time:04-28

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)

  • Related