ตัวย่อ XML
ย่อขนาด XML โดยลบช่องว่างและ comment ออก
ป้อนข้อมูล XML
XML ที่ย่อขนาดแล้ว
XML Minification คืออะไร?
XML minification คือกระบวนการลบอักขระที่ไม่จำเป็นทั้งหมดออกจากเอกสาร XML โดยไม่เปลี่ยนแปลงความหมาย ตัวย่อ XML จะลบช่องว่างระหว่าง tag, ลบ comment, ตัดการขึ้นบรรทัดใหม่ และย่อการย่อหน้าให้ได้ผลลัพธ์ที่กระชับในบรรทัดเดียว ผลลัพธ์คือ XML string ที่ parser อ่านได้เหมือนกับเวอร์ชันที่จัดรูปแบบแล้วทุกประการ ให้ข้อมูลเหมือนกันทุกอย่าง
ข้อกำหนด XML 1.0 (W3C Recommendation ฉบับที่ห้า) กำหนดกฎการจัดการช่องว่างในหัวข้อ 2.10 ช่องว่างระหว่าง tag ที่ไม่มีค่าเชิงความหมายเรียกว่า "insignificant whitespace" XML processor อนุญาตให้ละทิ้งช่องว่างดังกล่าวได้ อย่างไรก็ตาม ช่องว่างภายในเนื้อหาข้อความมีความหมายโดยค่าเริ่มต้น เว้นแต่ parent element จะประกาศ xml:space="default" ตัวย่อ XML ที่ถูกต้องจะแยกแยะสองกรณีนี้และลบเฉพาะสิ่งที่ปลอดภัยเท่านั้น
Minification แตกต่างจาก compression Gzip หรือ Brotli ลดขนาดที่ชั้น transport และต้องการขั้นตอน decompression ก่อน parse Minification ลดขนาดเอกสารดิบโดยตรง ทำให้ XML ยังคงถูกต้องและ parser ใดก็อ่านได้โดยไม่ต้องแตกไฟล์ก่อน ในทางปฏิบัติ การ minify ก่อน compress ให้ผลดีที่สุด: ลบอักขระซ้ำซ้อนก่อน จากนั้น compression algorithm จึงทำงานบนข้อมูลที่กระชับขึ้น
<?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>
ทำไมต้องใช้ตัวย่อ XML?
XML ที่จัดรูปแบบพร้อมการย่อหน้าและ comment เหมาะสำหรับการพัฒนาและ code review สำหรับการจัดเก็บ การส่งข้อมูล และการประมวลผลโดยเครื่อง การจัดรูปแบบพิเศษเหล่านั้นเพิ่มขนาดโดยไม่มีประโยชน์ ตัวย่อ XML ช่วยปิดช่องว่างนั้น
กรณีการใช้งานตัวย่อ XML
สิ่งที่ XML Minification ลบออก
ไม่ใช่ทุกอย่างในเอกสาร XML ที่ลบออกได้อย่างปลอดภัย ตารางอ้างอิงนี้แสดงแต่ละประเภทของเนื้อหาที่ลบได้และว่าการลบทิ้งนั้นปลอดภัยเสมอหรือขึ้นอยู่กับกรณีการใช้งาน
| รายการ | ตัวอย่าง | ความปลอดภัย |
|---|---|---|
| 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 |
Minification เทียบกับ Gzip เทียบกับ Binary Format
Minification, compression และ binary encoding ต่างมุ่งเป้าไปที่ชั้นต่างกันของปัญหาขนาด Minification คงผลลัพธ์เป็น XML ที่ถูกต้องและมนุษย์อ่านได้ Compression (gzip, Brotli) ลดขนาดได้มากกว่าแต่ต้องมีขั้นตอน decompression ก่อน parse Binary format ลดได้มากที่สุดแต่ทั้งสองฝั่งต้องมี encoder/decoder ที่เข้ากันได้ ใช้งานจริงส่วนใหญ่สำหรับระบบ embedded หรือบริการ enterprise ที่ใช้ WSDL หนัก
ตัวอย่างโค้ด
การย่อขนาด XML ด้วยโปรแกรมทำตามรูปแบบเดียวกันในทุกภาษา: parse เอกสารเป็น tree, ลบ comment node ตามต้องการ แล้ว serialize โดยไม่มีการย่อหน้า
// 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"