Skip to content
This repository has been archived by the owner on Dec 26, 2024. It is now read-only.

XML guide added (Issue #461) #607

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
321 changes: 321 additions & 0 deletions data/posts/ru/2023-06-06-xml.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,321 @@
---
title: Что такое XML?
description: Простыми словами про язык разметки XML
author: Прядко Максим
---

## Если вкратце

XML (*e**X**tensible **M**arkup **L**anguage*, то есть *«Расширяемый Язык Разметки»*) — это язык разметки, который используется для хранения и передачи данных (обычно из [API](https://guides.hexlet.io/ru/http-api/)), но не для отображения данных.

XML может быть прочитан как человеком, так и компьютером по аналогии с [JSON](https://tproger.ru/articles/chto-takoe-json-vvedenie/).

## Где используется XML?

Много где, например:

- Веб-сервисы: XML используется для передачи данных между веб-серверами и клиентскими приложениями. Например, [SOAP](https://ru.wikipedia.org/wiki/SOAP) (*Simple Object Access Protocol*) использует XML для кодирования запросов и ответов между веб-серверами и клиентами.

- Базы данных: XML может использоваться для представления данных.

- Конфигурационные файлы: файлы конфигурации веб-приложений могут быть написаны на XML.

- Интернет-магазины: XML используется для передачи информации о заказах между интернет-магазинами и поставщиками. Например, информация о заказах может быть сохранена в формате XML и передана поставщику через веб-сервис.

- Офисные приложения: XML может использоваться для представления данных в офисных приложениях, таких как Microsoft Excel и Microsoft Word. Документы Excel могут быть сохранены в формате XML.

- RSS-ленты: XML используется для создания [RSS-лент](https://ru.hexlet.io/programs/frontend/projects/11), которые используются для распространения новостей и другой информации на веб-сайтах.

## Структура

XML-документ состоит из **пролога**, **элементов**, **текста**, **атрибутов** и **комментариев**. Подобно HTML, каждый элемент может содержать другие элементы внутри себя.

#### Пролог

Любой XML-документ обычно начинается с объявления XML-версии и кодировки UTF. Всё вместе это называется **пролог**:

```xml
<?xml version="1.0" encoding="UTF-8"?>
```

Здесь `"1.0"` указывает на версию XML, а `"UTF-8"` указывает на кодировку символов.

#### Элементы

Далее следует **корневой элемент**, который содержит все **остальные элементы** в документе. Корневой элемент должен быть заключен в угловые скобки и иметь *открывающий* и *закрывающий* тег:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<frontend></frontend>
<backend />
</root>
```
В коде выше `root` является корневым элементом, а `frontend` и `backend` &mdash; остальными элементами.

**Важно!** Все тэги обязательно должны быть закрыты, даже одиночные. Иначе будут ошибки:

```xml

<?xml version="1.0" encoding="UTF-8"?>
<frameworks>
<vue>Vue</vue>
</frameworks>
```
```xml

<?xml version="1.0" encoding="UTF-8"?>
<frameworks>
<vue>Vue
</frameworks>
```

#### Текст

Каждый элемент может содержать **текст**, который находится между открывающим и закрывающим тегом:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<users>
<name>Иван</name>
</users>
```

Здесь `name` &mdash; это элемент, а `Иван` &mdash; это текст, содержащийся в элементе.

#### Атрибуты

Элементы также могут содержать **атрибуты**, которые определяют дополнительные характеристики элемента. Атрибуты указываются в открывающем теге элемента, у них есть свои имя и значение:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<user name="Иван" age="28" id="123"/>
</root>
```

Здесь `user` &mdash; это элемент, а `name`, `age` и `id` &mdash; атрибуты элемента.

#### Комментарии

**Комментарии** могут быть добавлены в XML-документ с помощью специальной конструкции `<!-- комментарий -->`:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<!-- Мой комментарий -->
</root>
```

## Конфликт имён и пространство имён

В HTML все теги заранее предопределены: есть `<h1>` для крупных заголовков, `<br />` для переноса строки или `<div>` для описания блочного элемента. В XML все теги мы определяем самостоятельно.

Допустим, мы хотим описать комнату и вещи, которые в ней находятся. В HTML есть специальный тег `<table>`, который определяет таблицу, поэтому добавим общий список всех объектов в комнате. А затем отдельно добавим компьютерный стол и тоже назовём его `<table>`.

И если в одном документе встретятся оба тега `<table>`, у которых разное значение, то произойдёт **конфликт имён**:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<room>
<table>
<tr>
<td>Мебель</td>
<td>Техника</td>
</tr>
</table>

<table>
<name>Компьютерный стол</name>
<material>ПВХ</material>
</table>
</room>
```
Чтобы избежать этого, используются **пространства имён**.

В XML-документе нужно сначала объявить пространство имен с помощью атрибута `xmlns`, который должен быть добавлен к корневому элементу. Значение атрибута `xmlns` указывает на [URI](https://ru.wikipedia.org/wiki/URI) (Uniform Resource Identifier), который идентифицирует пространство имен.

URI может быть каким угодно, но обычно используется URL, указывающий на документ, где определяется пространство имен.

Попробуем использовать пространства имён, чтобы разрешить конфликт имён:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<room xmlns:furniture="http://example.com/furniture" xmlns:tech="http://example.com/tech">
<furniture:table>
<tr>
<td>Стол</td>
<td>Кресло</td>
</tr>
</furniture:table>

<tech:table>
<name>Компьютерный стол</name>
<material>ПВХ</material>
</tech:table>
</room>
```
Здесь мы объявляем два пространства имен с URI `http://example.com/furniture` и `http://example.com/tech`.

Затем мы присваиваем каждому элементу свой уникальный идентификатор с помощью префикса пространства имен (`furniture:` и `tech:`). Теперь элементы `<table>` в разных пространствах имен не конфликтуют между собой, и мы можем использовать одно и то же имя элемента в разных контекстах.

## XSD-схема

XSD означает ***X**ML **S**chema **D**efinition* (*Определение XML-схемы*), а если ещё проще — это описание XML-документа.

Зачем это нужно? Представим, что у нас есть два разработчика: первый должен получить XML-документ, а второй должен отправить XML-документ. Первый разработчик составляет для второго XSD-схему, второй делает всё по ней и отправляет нам XML-документ.

Если проверка на типы данных и их организацию не проходят, то документ считается невалидным. Если всё проходит, значит с XML можно работать дальше. Очень удобно!

XSD определяет следующие типы данных:

- Простые типы: целые числа, строки, булевы значения, даты и другие простые типы данных.
- Сложные типы: состоят из набора элементов, которые могут содержать другие элементы.

Пример XSD-схемы для XML-документа, содержащего информацию о студентах:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="students">
<xs:complexType>
<xs:sequence>
<xs:element name="student" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="age" type="xs:int"/>
<xs:element name="address">
<xs:complexType>
<xs:sequence>
<xs:element name="city" type="xs:string"/>
<xs:element name="zip" type="xs:int"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
```
В этой схеме определен элемент `students`, который содержит неограниченное количество элементов `student`.

Каждый элемент **student** содержит элементы `name`, `age` и `address`.

Элемент **address** содержит вложенные элементы `city` и `zip`.

Также определены типы данных для каждого элемента, например, тип `xs:string` для элемента `name` и `xs:int` для элемента `age`, и так далее.

Эта схема определяет структуру, которую должен иметь XML-документ, чтобы он соответствовал требованиям. Например, каждый элемент `student` должен содержать элементы `name`, `age` и `address`, а элемент `address` должен содержать вложенные элементы `city` и `zip`.

А теперь посмотрим пример. Предположим, что у нас есть XML-документ, который описывает студентов:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student>
<namee>Юрий</namee>
<age>20</age>
<address>
<city>Архангельск</city>
<zip>163000</zip>
</address>
</student>
<student>
<name>Дарья</name>
<address>
<city>Санкт-Петербург</city>
<zip>187015</zip>
</address>
</student>
<student>
<name>Николай</name>
<age>22</age>
</student>
</students>
```

Всё ли в нём правильно? Нет, есть ошибки. Согласно схеме:

- У ***первого*** студента должен быть элемент `<name>`, а не `<namee>`
- У ***второго*** студента отсутствует `<age>`
- У ***третьего*** студента полностью отсутствует `<address>`

Теперь исправим всё недочёты:


```xml
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student>
<name>Юрий</name>
<age>20</age>
<address>
<city>Архангельск</city>
<zip>163000</zip>
</address>
</student>
<student>
<name>Дарья</name>
<age>19</age>
<address>
<city>Санкт-Петербург</city>
<zip>187015</zip>
</address>
</student>
<student>
<name>Николай</name>
<age>22</age>
<address>
<city>Вологда</city>
<zip>160000</zip>
</address>
</student>
</students>
```

Отлично! XML-документ прошёл валидацию и может быть обработан дальше.


## Вывод

В качестве вывода тезисно обозначим особенности XML:

- Предназначен для хранения и передачи данных, а не для отображения
- Все теги создаются с нуля, нужно придумывать их самому
- Код XML легко понятен человеку
- XML легко расширяемый, похожий на HTML
- В протоколе [SOAP](https://ru.wikipedia.org/wiki/SOAP) можно применять только XML
- XSD — это схема для определения XML-документа. Важно пользоваться ей, чтобы в XMl не было ошибок

Пример XSD-схемы:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="xs:string"/>
<xs:element name="published" type="xs:int"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
```

Пример XML-документа:

```xml
<book>
<title>Код. Тайный язык информатики</title>
<author>Ч. Петцольд</author>
<published>1999</published>
</book>
```