XML Minifier
Минифицируйте XML, удаляя пробелы и комментарии
Входные данные XML
Минифицированный XML
Что такое минификация XML?
Минификация XML — это процесс удаления всех ненужных символов из XML-документа без изменения его смысла. XML-минификатор убирает пробельные символы между тегами, удаляет комментарии, устраняет переносы строк и сворачивает отступы, формируя компактный однострочный вывод. В результате получается XML-строка, которую парсеры читают идентично исходной форматированной версии и извлекают из неё ту же модель данных.
Спецификация XML 1.0 (рекомендация W3C, пятое издание) определяет правила обработки пробелов в разделе 2.10. Пробелы между тегами, не несущие семантической нагрузки, называются «незначимыми пробелами» (insignificant whitespace). XML-процессорам разрешено отбрасывать их. Пробелы внутри текстового содержимого, напротив, значимы по умолчанию — если только родительский элемент не объявляет xml:space="default". Корректный XML-минификатор различает эти два случая и удаляет только то, что безопасно удалять.
Минификация отличается от сжатия. Gzip или Brotli уменьшают размер на транспортном уровне и требуют распаковки перед разбором. Минификация сокращает размер самого документа, поэтому XML остаётся валидным и пригодным для разбора любым парсером без шага декомпрессии. На практике минификация перед сжатием даёт наилучший результат: сначала удаляются избыточные символы, а затем алгоритм сжатия работает с более компактными входными данными.
<?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 Minifier?
XML с отступами и комментариями удобен при разработке и ревью кода. Для хранения, передачи и машинной обработки лишнее форматирование добавляет байты без какой-либо пользы. XML-минификатор устраняет этот разрыв.
Сценарии использования XML Minifier
Что удаляет минификация XML
Не всё в 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 |
Минификация, Gzip и бинарные форматы
Минификация, сжатие и бинарное кодирование решают проблему размера на разных уровнях. Минификация сохраняет вывод в виде валидного, читаемого XML. Сжатие (gzip, Brotli) сокращает размер дополнительно, но требует шага декомпрессии перед разбором. Бинарные форматы дают наибольшую степень сжатия, однако требуют совместимого кодировщика/декодировщика на обоих концах соединения — что актуально преимущественно для встраиваемых систем или корпоративных сервисов с тяжёлыми WSDL.
Примеры кода
Программная минификация XML следует одному и тому же паттерну в любом языке: разберите документ в дерево, при необходимости удалите узлы комментариев, затем сериализуйте без отступов.
// 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"