1. Знакомство с XML
Хотя JSON сегодня — стандарт, в Java-мире полно legacy-кода, поэтому иногда вы можете столкнуться с XML. Так что иметь о нём представление — полезно. XML (eXtensible Markup Language) — это текстовый формат для хранения и обмена структурированными данными. Его часто используют для конфигураций, обмена между программами, хранения данных и даже для сериализации объектов.
Основные элементы структуры XML-документа:
Теги (элементы):
Всё, что находится между < и >. Каждый тег открывается (<tag>) и закрывается (</tag>), либо самозакрывающийся (<tag/>).
Атрибуты:
Дополнительные параметры внутри тега.
Пример: <user name="Вася" age="25"/>
Текстовые узлы:
Текст между тегами.
Пример: <greeting>Привет, мир!</greeting>
Пример простого XML-документа
<?xml version="1.0" encoding="UTF-8"?>
<users>
<user name="Вася" age="25">Привет!</user>
<user name="Катя" age="30"/>
</users>
Здесь:
- <users> — корневой элемент.
- <user> — элемент с атрибутами name и age, у первого пользователя есть текстовое содержимое.
2. Ключевые понятия
Пролог:
Строка в начале файла указывает версию XML и кодировку.
Пример: <?xml version="1.0" encoding="UTF-8"?>
Элементы:
Основные строительные блоки XML.
Пример: <book>...</book>
Атрибуты:
Параметры внутри открывающего тега.
Пример: <book title="Java" author="Иванов"/>
Комментарии:
Как в HTML, пишутся между <!-- ... -->.
Пример: <!-- Это комментарий -->
CDATA-секции:
Позволяют вставлять текст, который не будет интерпретироваться как XML (например, с символами <, & и т.д.).
Пример:
<script><![CDATA[
if (a < b && b > 0) { ... }
]]></script>
3. Зачем нужны namespaces (пространства имён) в XML
Проблема: конфликт имён
В больших XML-документах часто встречаются одинаковые имена тегов, но с разным смыслом. Например, у вас есть <table> как часть HTML и <table> как часть вашей бизнес-логики (например, база данных). Как понять, какой тег что означает?
Без namespace:
<root>
<table>
<row>...</row>
</table>
<table>
<column>...</column>
</table>
</root>
Здесь непонятно, какой <table> относится к чему.
Решение: namespaces
Namespace (пространство имён) — это способ «пометить» элементы и атрибуты, чтобы избежать конфликтов имён и чётко разделять смысл разных тегов.
- Каждый namespace — это уникальный URI (обычно выглядит как ссылка, но это просто идентификатор).
- Элементы и атрибуты с разными namespace считаются разными, даже если имя совпадает.
Преимущества:
- Нет конфликтов имён между разными стандартами и схемами.
- Можно объединять данные из разных источников в одном документе.
- Явно видно, к какому «словарю» относится каждый тег.
4. Использование namespaces: объявление и применение
Как объявить namespace
В открывающем теге элемента пишется специальный атрибут xmlns (XML Namespace):
- Без префикса: xmlns="URI" — объявляет namespace по умолчанию для всех вложенных элементов.
- С префиксом: xmlns:prefix="URI" — объявляет namespace с коротким именем (префиксом), который используется для тегов.
Пример объявления и использования namespace
<root xmlns:h="http://www.w3.org/TR/html4/"
xmlns:f="http://www.w3schools.com/furniture">
<h:table>
<h:tr>
<h:td>Ячейка 1</h:td>
<h:td>Ячейка 2</h:td>
</h:tr>
</h:table>
<f:table>
<f:name>Стол</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
</root>
Здесь:
- xmlns:h="..." — объявляет префикс h для HTML-таблицы.
- xmlns:f="..." — объявляет префикс f для мебели.
- <h:table> и <f:table> — теперь это разные элементы, даже если имя одинаковое.
Как использовать namespace
- Объявление: В корневом или любом другом элементе: xmlns:prefix="URI"
- Применение: Перед именем элемента или атрибута пишется префикс и двоеточие: <prefix:element>...</prefix:element>
Namespace по умолчанию
Если объявить просто xmlns="URI", все элементы без префикса будут относиться к этому namespace.
<books xmlns="http://example.com/books">
<book>...</book>
</books>
5. Практика: создание простого XML-документа с несколькими namespaces
Давайте создадим пример XML-документа, где используются два пространства имён: для HTML и для мебели.
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:h="http://www.w3.org/TR/html4/"
xmlns:f="http://www.w3schools.com/furniture">
<h:table>
<h:tr>
<h:td>Ячейка 1</h:td>
<h:td>Ячейка 2</h:td>
</h:tr>
</h:table>
<f:table>
<f:name>Стол</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
</root>
Что здесь происходит:
- В корневом элементе объявлены два namespace: h и f.
- Все элементы с префиксом h: относятся к HTML-таблице.
- Все элементы с префиксом f: относятся к мебели.
6. Типичные ошибки
Ошибка 1: забыли объявить префикс
<root>
<h:table>...</h:table>
</root>
Результат: Парсер XML выдаст ошибку: The prefix 'h' for element 'h:table' is not bound.
Ошибка 2: одинаковые имена без namespace
<root>
<table>...</table>
<table>...</table>
</root>
Результат: Невозможно различить, какой <table> к чему относится.
Ошибка 3: неправильное использование префикса
<root xmlns:h="http://www.w3.org/TR/html4/">
<h:table>...</h:table>
<f:table>...</f:table> <!-- Ошибка: префикс f не объявлен -->
</root>
Результат: Ошибка парсера: The prefix 'f' for element 'f:table' is not bound.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ