首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用python从JSON到XML转换(dicttoxml)

用python从JSON到XML转换(dicttoxml)
EN

Stack Overflow用户
提问于 2022-04-27 08:24:16
回答 1查看 108关注 0票数 0
代码语言:javascript
复制
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)

当前产出:

代码语言:javascript
复制
<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>

我使用程序包将JSON转换为,对话进行得很顺利。但是我有一个场景,其中JSON键以_开头。在该场景中,需要JSON键,值必须是XML父标记的一部分,如下所示。

预期产出;

代码语言:javascript
复制
<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>

是否有一种方法可以使用程序包来实现这一点,或者是否有其他软件包支持这些场景?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-27 12:20:16

我不认为dicttoxml包含这样一个特定的函数。但是,您可以轻松地使用ElementTree对xml进行所有的更改。

代码语言:javascript
复制
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'))

输出:

代码语言:javascript
复制
<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>

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

代码语言:javascript
复制
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上循环)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72025532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档