Trình Rút Gọn XML
Rút gọn XML bằng cách xóa khoảng trắng và chú thích
Nhập XML
XML Đã Rút Gọn
Rút gọn XML là gì?
Rút gọn XML là quá trình loại bỏ tất cả các ký tự không cần thiết khỏi một tài liệu XML mà không thay đổi ý nghĩa của nó. Một công cụ rút gọn XML xóa khoảng trắng giữa các thẻ, loại bỏ chú thích, xóa ngắt dòng và thu gọn thụt lề để tạo ra đầu ra gọn gàng trên một dòng duy nhất. Kết quả là một chuỗi XML mà các trình phân tích đọc giống hệt với phiên bản được định dạng ban đầu, tạo ra cùng một mô hình dữ liệu.
Đặc tả XML 1.0 (Khuyến nghị W3C, ấn bản thứ năm) định nghĩa các quy tắc xử lý khoảng trắng trong mục 2.10. Khoảng trắng giữa các thẻ không có giá trị ngữ nghĩa được gọi là "khoảng trắng không quan trọng". Các bộ xử lý XML được phép bỏ qua nó. Tuy nhiên, khoảng trắng bên trong nội dung văn bản mặc định là có ý nghĩa, trừ khi phần tử cha khai báo xml:space="default". Một công cụ rút gọn XML đúng đắn phân biệt giữa hai trường hợp này và chỉ xóa những gì an toàn để xóa.
Rút gọn khác với nén. Gzip hoặc Brotli giảm kích thước ở tầng truyền tải và yêu cầu giải nén trước khi phân tích. Rút gọn giảm kích thước của tài liệu gốc, vì vậy XML vẫn hợp lệ và có thể đọc được bởi bất kỳ trình phân tích nào mà không cần bước giải nén. Trên thực tế, rút gọn trước khi nén mang lại kết quả tốt nhất: bạn loại bỏ các ký tự dư thừa trước, sau đó thuật toán nén hoạt động trên đầu vào nhỏ gọn hơn.
<?xml version="1.0" encoding="UTF-8"?>
<!-- Product catalog for Q1 2026 -->
<catalog>
<product id="p101">
<name>Widget A</name>
<price currency="USD">29.99</price>
<!-- Temporarily discounted -->
<stock>142</stock>
</product>
<product id="p102">
<name>Widget B</name>
<price currency="EUR">19.50</price>
<stock>87</stock>
</product>
</catalog><?xml version="1.0" encoding="UTF-8"?><catalog><product id="p101"><name>Widget A</name><price currency="USD">29.99</price><stock>142</stock></product><product id="p102"><name>Widget B</name><price currency="EUR">19.50</price><stock>87</stock></product></catalog>
Tại sao sử dụng công cụ rút gọn XML?
XML được định dạng với thụt lề và chú thích rất lý tưởng cho quá trình phát triển và xem xét mã. Đối với lưu trữ, truyền tải và tiêu thụ bởi máy tính, định dạng thêm đó chỉ tốn thêm byte mà không mang lại lợi ích gì. Công cụ rút gọn XML lấp đầy khoảng trống đó.
Các trường hợp sử dụng công cụ rút gọn XML
Những gì rút gọn XML loại bỏ
Không phải mọi thứ trong tài liệu XML đều có thể xóa một cách an toàn. Bảng tham chiếu này cho thấy từng loại nội dung có thể xóa và liệu việc loại bỏ đó có luôn an toàn hay phụ thuộc vào trường hợp sử dụng của bạn.
| Mục | Ví dụ | Độ an toàn |
|---|---|---|
| Indentation | Spaces/tabs before tags | Always safe to remove |
| Line breaks | \n and \r\n between tags | Always safe to remove |
| Comments | <!-- ... --> | Safe unless parsed by app |
| XML declaration | <?xml version="1.0"?> | Keep if encoding is non-UTF-8 |
| Processing instructions | <?xml-stylesheet ...?> | Keep if consumed downstream |
| Trailing whitespace | Spaces after closing tags | Always safe to remove |
| Text node whitespace | Spaces inside text content | Remove only between tags, not within |
Rút gọn vs Gzip vs Định dạng nhị phân
Rút gọn, nén và mã hóa nhị phân mỗi loại nhắm đến một tầng khác nhau của vấn đề kích thước. Rút gọn giữ đầu ra là XML hợp lệ, có thể đọc được bởi con người. Nén (gzip, Brotli) giảm thêm nhưng yêu cầu bước giải nén trước khi phân tích. Định dạng nhị phân giảm nhiều hơn nữa, nhưng cả hai đầu kết nối đều cần bộ mã hóa/giải mã tương thích — chủ yếu thực tế đối với các hệ thống nhúng hoặc dịch vụ doanh nghiệp nặng WSDL.
Ví dụ mã
Rút gọn XML theo chương trình theo cùng một mẫu trong mọi ngôn ngữ: phân tích tài liệu thành cây, tùy chọn xóa các nút chú thích, sau đó tuần tự hóa mà không có thụt lề.
// Minify XML by parsing and re-serializing (strips formatting)
const raw = `<root>
<item id="1">
<!-- note -->
<name>Test</name>
</item>
</root>`
const parser = new DOMParser()
const doc = parser.parseFromString(raw, 'application/xml')
// Remove comment nodes
const walker = doc.createTreeWalker(doc, NodeFilter.SHOW_COMMENT)
const comments = []
while (walker.nextNode()) comments.push(walker.currentNode)
comments.forEach(c => c.parentNode.removeChild(c))
const minified = new XMLSerializer().serializeToString(doc)
// → "<root><item id=\"1\"><name>Test</name></item></root>"from lxml import etree
xml = """<root>
<item id="1">
<!-- note -->
<name>Test</name>
</item>
</root>"""
tree = etree.fromstring(xml.encode())
# Remove comments
for comment in tree.iter(etree.Comment):
comment.getparent().remove(comment)
# Serialize without pretty-print (minified)
result = etree.tostring(tree, xml_declaration=False).decode()
# → '<root><item id="1"><name>Test</name></item></root>'
# With xml.etree (stdlib, no lxml needed)
import xml.etree.ElementTree as ET
root = ET.fromstring(xml)
ET.indent(root, space='') # Python 3.9+
print(ET.tostring(root, encoding='unicode'))package main
import (
"encoding/xml"
"fmt"
"strings"
)
func minifyXML(input string) (string, error) {
decoder := xml.NewDecoder(strings.NewReader(input))
var out strings.Builder
encoder := xml.NewEncoder(&out)
// No indentation = minified output
for {
tok, err := decoder.Token()
if err != nil {
break
}
// Skip comments
if _, ok := tok.(xml.Comment); ok {
continue
}
// Skip whitespace-only char data
if cd, ok := tok.(xml.CharData); ok {
if strings.TrimSpace(string(cd)) == "" {
continue
}
}
encoder.EncodeToken(tok)
}
encoder.Flush()
return out.String(), nil
}
// minifyXML("<a>\n <b>1</b>\n</a>") → "<a><b>1</b></a>"# Minify XML with xmllint (part of libxml2) xmllint --noblanks input.xml > minified.xml # Minify from stdin echo '<root> <item>hello</item> </root>' | xmllint --noblanks - # → <?xml version="1.0"?><root><item>hello</item></root> # Strip comments too (combine with sed or xmlstarlet) xmlstarlet ed -d '//comment()' input.xml | xmllint --noblanks - # Check size reduction echo "Before: $(wc -c < input.xml) bytes" echo "After: $(xmllint --noblanks input.xml | wc -c) bytes"