0
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?

1 Answer 1

2

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)

Sign up to request clarification or add additional context in comments.

2 Comments

it worked fine, thanks, but the key "PhoneNumber" is dynamic, I may get any key name in the JSON, how can I handle that?
I edited my answer, check it out!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.