Minifikator XML
Minifikuj XML, usuwając spacje i komentarze
Wejście XML
Zminifikowany XML
Czym jest minifikacja XML?
Minifikacja XML to proces usuwania wszystkich zbędnych znaków z dokumentu XML bez zmiany jego znaczenia. Minifikator XML usuwa białe znaki między tagami, kasuje komentarze, eliminuje podziały wierszy i zwija wcięcia, aby wytworzyć zwartą, jednowierszową postać dokumentu. Wynik to ciąg XML, który parsery odczytują identycznie jak oryginalną sformatowaną wersję — uzyskując ten sam model danych.
Specyfikacja XML 1.0 (zalecenie W3C, wydanie piąte) definiuje zasady obsługi białych znaków w sekcji 2.10. Białe znaki między tagami, które nie mają wartości semantycznej, są nazywane "nieistotnymi białymi znakami". Procesory XML mogą je pomijać. Białe znaki wewnątrz treści tekstowej są jednak domyślnie znaczące, chyba że element nadrzędny deklaruje xml:space="default". Prawidłowy minifikator XML rozróżnia te dwa przypadki i usuwa tylko to, co jest bezpieczne do usunięcia.
Minifikacja różni się od kompresji. Gzip i Brotli zmniejszają rozmiar na warstwie transportowej i wymagają dekompresji przed parsowaniem. Minifikacja zmniejsza rozmiar samego dokumentu, więc XML pozostaje poprawny i czytelny dla każdego parsera bez kroku dekompresji. W praktyce minifikacja przed kompresją daje najlepsze wyniki: najpierw eliminujesz redundantne znaki, a następnie algorytm kompresji działa na zwartym wejściu.
<?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>
Dlaczego warto używać minifikatora XML?
Sformatowany XML z wcięciami i komentarzami idealnie sprawdza się podczas programowania i przeglądu kodu. Do przechowywania, przesyłania i przetwarzania maszynowego to dodatkowe formatowanie generuje bajty bez żadnej korzyści. Minifikator XML likwiduje tę lukę.
Zastosowania minifikatora XML
Co minifikacja XML usuwa
Nie wszystko w dokumencie XML można bezpiecznie usunąć. Poniższa tabela pokazuje każdy rodzaj usuwalnej treści oraz to, czy jej odrzucenie jest zawsze bezpieczne, czy też zależy od konkretnego zastosowania.
| Element | Przykład | Bezpieczeństwo |
|---|---|---|
| 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 |
Minifikacja a Gzip a formaty binarne
Minifikacja, kompresja i kodowanie binarne celują w różne warstwy problemu rozmiaru. Minifikacja zachowuje wynik jako poprawny, czytelny dla człowieka XML. Kompresja (gzip, Brotli) zmniejsza go dalej, ale wymaga kroku dekompresji przed parsowaniem. Formaty binarne idą najdalej, ale obie strony połączenia potrzebują zgodnego kodera/dekodera — co jest praktyczne głównie w systemach wbudowanych lub usługach enterprise o rozbudowanym WSDL.
Przykłady kodu
Minifikacja XML programistyczna przebiega według tego samego wzorca w każdym języku: sparsuj dokument do drzewa, opcjonalnie usuń węzły komentarzy, a następnie serializuj bez wcięć.
// 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"