XML sang JSON
Chuyển đổi XML sang định dạng JSON
Nhập XML
Xuất JSON
Chuyển đổi XML sang JSON là gì?
Chuyển đổi XML sang JSON là quá trình biến đổi dữ liệu từ Extensible Markup Language (XML) sang JavaScript Object Notation (JSON). Cả hai định dạng đều biểu diễn dữ liệu có cấu trúc phân cấp, nhưng sử dụng cú pháp và mô hình dữ liệu khác nhau. XML dùng thẻ mở và đóng kèm thuộc tính tùy chọn, trong khi JSON dùng cặp khóa-giá trị, mảng và kiểu nguyên thủy. Chuyển đổi XML sang JSON cho phép bạn làm việc với dữ liệu XML trong các môi trường mà JSON là định dạng gốc, chẳng hạn như JavaScript runtime, REST API và cơ sở dữ liệu NoSQL.
Việc chuyển đổi không phải lúc nào cũng tương đương một-một. XML có các cấu trúc không có tương đương trực tiếp trong JSON: thuộc tính, nội dung hỗn hợp (văn bản xen kẽ với phần tử con), chỉ thị xử lý, chú thích, phần CDATA và khai báo không gian tên. Các thư viện chuyển đổi khác nhau xử lý những cấu trúc này theo cách khác nhau, đó là lý do tồn tại nhiều quy ước. Cách phổ biến nhất là thêm tiền tố @ vào tên thuộc tính và đặt nội dung văn bản vào trường #text khi phần tử vừa có thuộc tính vừa có văn bản.
Chuyển đổi XML sang JSON là bước thường gặp khi di chuyển từ SOAP sang REST, sử dụng các API doanh nghiệp kế thừa, hoặc xử lý luồng dữ liệu chính phủ và tài chính yêu cầu XML. Thay vì viết lại cả phía phát và phía nhận cùng lúc, các nhóm chuyển đổi tải trọng XML tại lớp biên và truyền JSON xuống phía sau. AWS API Gateway, Apache Camel và MuleSoft đều hỗ trợ mẫu này theo cách gốc.
<bookstore>
<book category="fiction">
<title lang="en">The Great Gatsby</title>
<author>F. Scott Fitzgerald</author>
<year>1925</year>
<price>10.99</price>
</book>
<book category="non-fiction">
<title lang="en">Sapiens</title>
<author>Yuval Noah Harari</author>
<year>2011</year>
<price>14.99</price>
</book>
</bookstore>{
"bookstore": {
"book": [
{
"@category": "fiction",
"title": {
"@lang": "en",
"#text": "The Great Gatsby"
},
"author": "F. Scott Fitzgerald",
"year": "1925",
"price": "10.99"
},
{
"@category": "non-fiction",
"title": {
"@lang": "en",
"#text": "Sapiens"
},
"author": "Yuval Noah Harari",
"year": "2011",
"price": "14.99"
}
]
}
}Tại sao sử dụng công cụ chuyển đổi XML sang JSON trực tuyến?
Viết một đoạn script chuyển đổi riêng lẻ tốn thời gian, đặc biệt khi XML chứa thuộc tính, không gian tên hoặc các phần tử lặp lại cần trở thành mảng JSON. Một công cụ chạy trên trình duyệt cho đầu ra JSON trong vài giây để bạn kiểm tra cấu trúc và tiếp tục công việc.
Các trường hợp sử dụng chuyển đổi XML sang JSON
Tham chiếu ánh xạ XML sang JSON
XML và JSON có mô hình dữ liệu khác nhau. Bảng dưới đây cho thấy cách mỗi cấu trúc XML ánh xạ sang tương đương JSON theo quy ước phổ biến nhất (@ cho thuộc tính, #text cho văn bản khi có cả thuộc tính). Một số cấu trúc như nội dung hỗn hợp và chú thích không có biểu diễn JSON chuẩn.
| Cấu trúc XML | Ví dụ XML | Tương đương JSON |
|---|---|---|
| Element | <name>text</name> | "name": "text" |
| Nested elements | <a><b>1</b></a> | "a": { "b": "1" } |
| Attributes | <el attr="v"/> | "el": { "@attr": "v" } |
| Text + attributes | <el a="1">text</el> | "el": { "@a": "1", "#text": "text" } |
| Repeated elements | <r><i>1</i><i>2</i></r> | "r": { "i": ["1", "2"] } |
| Mixed content | <p>A <b>B</b> C</p> | Varies by convention |
| CDATA | <![CDATA[raw]]> | "#cdata": "raw" or flattened |
| Namespaces | xmlns:prefix="uri" | Prefix preserved or stripped |
| Empty element | <el/> | "el": null or "" |
| Comments | <!-- note --> | Discarded (no JSON equivalent) |
So sánh các quy ước chuyển đổi XML sang JSON
Không có tiêu chuẩn duy nhất nào quy định cách XML ánh xạ sang JSON. Ba quy ước được sử dụng rộng rãi, mỗi quy ước có sự đánh đổi khác nhau về xử lý thuộc tính, phát hiện mảng và bảo toàn văn bản.
Ví dụ mã nguồn
Dưới đây là các ví dụ hoạt động để chuyển đổi XML sang JSON trong JavaScript, Python, Go và dòng lệnh. Mỗi ví dụ xử lý các phần tử lồng nhau và các thẻ anh em lặp lại.
// Using the DOMParser API to walk XML and build a JSON object
function xmlToJson(xml) {
const parser = new DOMParser()
const doc = parser.parseFromString(xml, 'application/xml')
function nodeToObj(node) {
const obj = {}
// Handle attributes
if (node.attributes) {
for (const attr of node.attributes) {
obj['@' + attr.name] = attr.value
}
}
// Handle child nodes
for (const child of node.childNodes) {
if (child.nodeType === 3) { // text
const text = child.textContent.trim()
if (text) obj['#text'] = text
} else if (child.nodeType === 1) { // element
const key = child.nodeName
const val = nodeToObj(child)
if (obj[key]) {
if (!Array.isArray(obj[key])) obj[key] = [obj[key]]
obj[key].push(val)
} else {
obj[key] = val
}
}
}
// Simplify text-only nodes
const keys = Object.keys(obj)
if (keys.length === 1 && keys[0] === '#text') return obj['#text']
return obj
}
return nodeToObj(doc.documentElement)
}
const xml = '<user><name>Alice</name><role>admin</role></user>'
console.log(JSON.stringify(xmlToJson(xml), null, 2))
// → { "name": "Alice", "role": "admin" }import xmltodict
import json
xml = """
<user>
<name>Alice</name>
<roles>
<role>admin</role>
<role>editor</role>
</roles>
</user>
"""
# xmltodict converts XML to an OrderedDict
result = xmltodict.parse(xml)
print(json.dumps(result, indent=2))
# → {
# → "user": {
# → "name": "Alice",
# → "roles": { "role": ["admin", "editor"] }
# → }
# → }
# With the standard library (xml.etree.ElementTree)
import xml.etree.ElementTree as ET
def etree_to_dict(elem):
d = {}
if elem.attrib:
d.update({f"@{k}": v for k, v in elem.attrib.items()})
for child in elem:
child_data = etree_to_dict(child)
if child.tag in d:
if not isinstance(d[child.tag], list):
d[child.tag] = [d[child.tag]]
d[child.tag].append(child_data)
else:
d[child.tag] = child_data
if elem.text and elem.text.strip():
if d:
d["#text"] = elem.text.strip()
else:
return elem.text.strip()
return d
root = ET.fromstring(xml)
print(json.dumps(etree_to_dict(root), indent=2))package main
import (
"encoding/json"
"encoding/xml"
"fmt"
"strings"
)
// For simple, known schemas — define a struct
type User struct {
XMLName xml.Name `xml:"user"`
Name string `xml:"name"`
Roles []string `xml:"roles>role"`
}
func main() {
data := `<user><name>Alice</name><roles><role>admin</role><role>editor</role></roles></user>`
var user User
xml.NewDecoder(strings.NewReader(data)).Decode(&user)
out, _ := json.MarshalIndent(user, "", " ")
fmt.Println(string(out))
// → { "Name": "Alice", "Roles": ["admin", "editor"] }
}# Using xq (part of yq, a jq wrapper for XML)
# Install: pip install yq OR brew install yq
echo '<user><name>Alice</name></user>' | xq .
# → { "user": { "name": "Alice" } }
# Using xmlstarlet + jq
xmlstarlet sel -t -v '//name' input.xml | jq -R '{ name: . }'
# Node.js one-liner with xml2js
echo '<a><b>1</b></a>' | node -e "
const {parseString} = require('xml2js');
let d=''; process.stdin.on('data',c=>d+=c);
process.stdin.on('end',()=>parseString(d,(e,r)=>console.log(JSON.stringify(r,null,2))))
"