XML và JSON là 2 định dạng (format) dữ liệu được sử dụng phổ biến nhất hiện nay. Trong Python, chúng ta có thể chuyển đổi (convert) giữa 2 định dạng dữ liệu này. Bài này sẽ sử dụng module json và ElementTree để convert JSON sang XML trong Python.
Trước khi đọc bài này, các bạn nên đọc các bài về XML và JSON trong Python sau:
- Đọc (read) file XML với Python
- Ghi (write) file XML với Python
- Đọc (read) file JSON với Python
- Ghi (write) file JSON với Python
1. Các bước convert JSON sang XML trong Python
Các bước chuyển đổi (convert) dữ liệu JSON thành dữ liệu XML trong Python như sau:
Bước 1. Import thư viện json, ElementTree
import json
import xml.etree.ElementTree as ET
from xml.dom import minidom
Chúng ta sử dụng module minidom để tạo ra XML string với thụt đầu dòng bằng ký tự “\t” giúp cho dữ liệu XML dễ đọc hơn.
Bước 2. Đọc dữ liệu trong file JSON và chuyển đổi thành dictionary với hàm json.load()
Bước 3. Sử dụng module ElementTree để tạo các thẻ XML. Thuộc tính và text của các thẻ XML được truy xuất từ dictionary được chuyển đổi từ dữ liệu JSON ở bước 2.
Bước 4. Chuyển dữ liệu XML thành string rồi ghi (write) XML string vào file.
2. Ví dụ convert JSON sang XML
Giả sử, chúng ta chúng ta có file info.json
với nội dung như bên dưới.
{
"domainname": "gochocit.com",
"active": true,
"numberposts": 360,
"category": {
"item": [
{
"@post": 50,
"#text": "hardware"
},
{
"@post": 150,
"#text": "software"
},
{
"@post": 17,
"#text": "network"
}
]
},
"facebookpage": "https://www.facebook.com/gochocit/",
"build": {
"language": "php",
"cms": "wordpress",
"database": "mysql"
}
}
Bên dưới là đoạn code giúp convert dữ liệu JSON thành dữ liệu XML.
import json
import xml.etree.ElementTree as ET
from xml.dom import minidom
# read json file
with open("info.json") as json_file:
data_json = json.load(json_file)
# create root tag
website = ET.Element('website')
# domainname tag
domainname = ET.SubElement(website, 'domainname')
domainname.text = data_json["domainname"]
# active tag
active = ET.SubElement(website, 'active')
active.text = str(data_json["active"])
# numberposts tag
numberposts = ET.SubElement(website, 'numberposts')
numberposts.text = str(data_json["numberposts"])
# category tag
category = ET.SubElement(website, 'category')
# item1 tag of category tag
item1 = ET.SubElement(category, 'item')
item1.set("post", str(data_json["category"]["item"][0]["@post"]))
item1.text = data_json["category"]["item"][0]["#text"]
# item2 tag of category tag
item2 = ET.SubElement(category, 'item')
item2.set("post", str(data_json["category"]["item"][1]["@post"]))
item2.text = data_json["category"]["item"][1]["#text"]
# item3 tag of category tag
item3 = ET.SubElement(category, 'item')
item3.set("post", str(data_json["category"]["item"][2]["@post"]))
item3.text = data_json["category"]["item"][2]["#text"]
# facebookpage tag
facebookpage = ET.SubElement(website, 'facebookpage')
facebookpage.text = data_json["facebookpage"]
# build tag
build = ET.SubElement(website, 'build')
# language tag of build tag
language = ET.SubElement(build, 'language')
language.text = data_json["build"]["language"]
# cms tag of build tag
cms = ET.SubElement(build, 'cms')
cms.text = data_json["build"]["cms"]
# database tag of build tag
database = ET.SubElement(build, 'database')
database.text = data_json["build"]["database"]
# create a pretty XML string
mydata = ET.tostring(website, encoding='unicode')
mydata_minidom = minidom.parseString(mydata)
pretty_mydata = mydata_minidom.toprettyxml(indent="\t")
# create a new XML file
myxmlfile = open("info.xml", "w")
myxmlfile.write(pretty_mydata)
myxmlfile.close()
Kết quả file info.xml được tạo ra
<?xml version="1.0" ?>
<website>
<domainname>gochocit.com</domainname>
<active>True</active>
<numberposts>360</numberposts>
<category>
<item post="50">hardware</item>
<item post="150">software</item>
<item post="17">network</item>
</category>
<facebookpage>https://www.facebook.com/gochocit/</facebookpage>
<build>
<language>php</language>
<cms>wordpress</cms>
<database>mysql</database>
</build>
</website>
Lưu ý: Cần chuyển các dữ liệu có kiểu dữ liệu là boolean, number trong JSON sang string với hàm str()
khi convert JSON sang XML.