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>我使用程序包将JSON转换为,对话进行得很顺利。但是我有一个场景,其中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>是否有一种方法可以使用程序包来实现这一点,或者是否有其他软件包支持这些场景?
发布于 2022-04-27 12:20:16
我不认为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>编辑:对于直接位于根下的所有键(不仅仅是"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上循环)
https://stackoverflow.com/questions/72025532
复制相似问题