JSON 到 XML 的转换 python (dicttoxml)

JSON to XML conversion with python (dicttoxml)

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)

当前输出:

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

我正在使用 dicttoxml 包将 JSON 转换为 XML,对话进展顺利。但我有一个 JSON 键以 _ 开头的场景。在那种情况下需要 JSON 键和值必须是 XML 父标签的一部分,如下所示。

预期输出;

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

有没有办法使用 dicttoxml 包来实现这一点,或者是否有任何其他支持这些场景的包?

我不认为 dicttoxml 包含这样的特定功能。但是,您可以使用 ElementTree:

轻松地对 xml 进行所有想要的更改
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'))

输出:

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

编辑:对于直接位于 root 下的所有键(不仅是“PhoneNumber”),将循环替换为:

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)

(如果要递归处理所有元素,则循环 elt_tree.iter() 而不是 elt_tree