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