XML

Формат обмена данными, который любят в энтерпрайзе.

Время чтения: 6 мин

Кратко

Скопировано

XML (Extensible Markup Language) — расширяемый язык разметки. По структуре напоминает HTML. XML отличается тем, что теги для разметки разработчик должен определять самостоятельно. Используется для передачи данных между приложениями по аналогии с JSON.

Как пишется

Скопировано

Корневой элемент

Скопировано

У XML-документа обязательно должен быть один корневой элемент, который будет родительским для остальных элементов. В примере ниже <root> является корневым элементом:

        
          
          <?xml version="1.0" encoding="UTF-8"?><root>  <tree>    <leaf>Тут лежит листик</leaf>    <leaf>Тут лежит листик</leaf>  </tree></root>
          <?xml version="1.0" encoding="UTF-8"?>
<root>
  <tree>
    <leaf>Тут лежит листик</leaf>
    <leaf>Тут лежит листик</leaf>
  </tree>
</root>

        
        
          
        
      

XML-пролог

Скопировано

Любой XML-документ обычно начинается со специальной строки, которая называется пролог. Он обозначает, с какой версией документа мы работаем. Пролог содержит версию и кодировку, которая используется:

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

        
        
          
        
      

Пролог для XML не обязателен, но если вы решили его указать, то нужно сделать это в самом начале документа. Он должен быть первым.

Теги

Скопировано

Основное правило для написания XML-документа — всегда закрывайте теги. Даже одиночные!
Правильно закрытые теги:

        
          
          <?xml version="1.0" encoding="UTF-8"?><animals>  <cat>Борись и не сдавайся!</cat>  <dog /></animals>
          <?xml version="1.0" encoding="UTF-8"?>
<animals>
  <cat>Борись и не сдавайся!</cat>
  <dog />
</animals>

        
        
          
        
      

Если не закрыть тег, вся сила утекает из кода, и обработка выдаст ошибку:

        
          
          <?xml version="1.0" encoding="UTF-8"?><cat>Энергия кота Бориса утекает от нас<dog>
          <?xml version="1.0" encoding="UTF-8"?>
<cat>Энергия кота Бориса утекает от нас
<dog>

        
        
          
        
      

Структура

Скопировано

Документ состоит из разных сущностей, которые состоят из символов. Символы делятся на символы разметки и символы данных. К символам разметки, они же символы структуры документа, относятся:

Теги

Скопировано

Теги обозначают границы элементов. Одни могут содержать в себе текст, другие — теги, атрибуты или их сочетание. Например, определим сущность <petstore> для магазина домашних любимцев. В нём у нас есть несколько видов животных — <pet>. Эти два тега содержат в себе дочерние элементы — тоже теги.

У каждого питомца мы определили его вид с помощью атрибута category. У нас есть категории: cat, dog, fish. Дополнительная информация о питомце содержится в тегах <name>, <year>, <price>:

        
          
          <?xml version="1.0" encoding="UTF-8"?><petstore>  <pet category="cat">    <name>Борис</name>    <year>2021</year>    <price>485.00</price>  </pet>  <pet category="dog">    <name>Плуто</name>    <year>2020</year>    <price>2999.99</price>  </pet>  <pet category="fish">    <name>Нэмо</name>    <year>2021</year>    <price>100.50</price>  </pet></petstore>
          <?xml version="1.0" encoding="UTF-8"?>
<petstore>
  <pet category="cat">
    <name>Борис</name>
    <year>2021</year>
    <price>485.00</price>
  </pet>
  <pet category="dog">
    <name>Плуто</name>
    <year>2020</year>
    <price>2999.99</price>
  </pet>
  <pet category="fish">
    <name>Нэмо</name>
    <year>2021</year>
    <price>100.50</price>
  </pet>
</petstore>

        
        
          
        
      

Элементы могут быть пустыми или самозакрывающимися, например:

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

        
        
          
        
      

Атрибуты

Скопировано

Атрибуты хранят определённую информацию, которая относится к конкретному элементу. Значения атрибутов должны быть указаны в кавычках, одинарных и двойных:

        
          
          <pets>  <pet category="cat" />  <pet category='dog' />  <pet category='dog "corgi"' /></pets>
          <pets>
  <pet category="cat" />
  <pet category='dog' />
  <pet category='dog "corgi"' />
</pets>

        
        
          
        
      

Конфликты именования тегов

Скопировано

Так как в XML мы сами определяем имена для тегов, то есть вероятность возникновения конфликта имён. Если мы определим таблицу в XML тегами из HTML, то возникнет конфликт. Первый XML-код содержит информацию таблицы HTML, второй — описание кота. Если эти два фрагмента кода были сложены вместе, то возник бы конфликт имён. Они оба определены тегом <table>, но у них разное содержание. XML не знает как подружить эти разные структуры.

        
          
          <root>  <table>    <tr>      <th>Заголовок 1</th>      <th>Заголовок 2</th>    </tr>    <tr>      <td>Элемент 1</td>      <td>Элемент 2</td>    </tr>  </table>  <table>    <cat>Кот</cat>    <name>Борис</name>  </table></root>
          <root>
  <table>
    <tr>
      <th>Заголовок 1</th>
      <th>Заголовок 2</th>
    </tr>
    <tr>
      <td>Элемент 1</td>
      <td>Элемент 2</td>
    </tr>
  </table>

  <table>
    <cat>Кот</cat>
    <name>Борис</name>
  </table>
</root>

        
        
          
        
      

Можно разрешить эту проблему, если определить пространство имён. Для двух этих таблиц нужно добавить атрибут xmlns с указанием урла на документ с пространством имён:

        
          
          <table xmlns="https://www.w3.org/TR/html51/" />
          <table xmlns="https://www.w3.org/TR/html51/" />

        
        
          
        
      

Пространство имён помогает сохранить уникальность наименований. Стоит отметить, что добавление пространства имён накладывает ограничение на теги и атрибуты. Если мы ссылаемся на пространство имён, то можно использовать только те элементы, которые определены в этом пространстве. Нельзя задавать ссылку на локальный документ и нельзя определять xmlns как пустую строку.

Определим два пространства имён с помощью xmlns для разных таблиц: classic и catName, чтобы из XML можно было корректно считать данные. Пространства определены в ссылках, поэтому наименование строгое и должно соответствовать определению.

После введения атрибута xmlns необходимо добавить тегам префиксы с двоеточием classic: и catName:, тогда код будет обрабатываться правильно и выглядеть так:

        
          
          <root><root>  <classic:table xmlns:classic="https://www.w3.org/TR/html51">    <classic:tr>      <classic:th>Заголовок 1</classic:th>      <classic:th>Заголовок 2</classic:th>    </classic:tr>    <classic:tr>      <classic:td>Элемент 1</classic:td>      <classic:td>Элемент 2</classic:td>    </classic:tr>  </classic:table>  <catName:table xmlns:catName="https://catNameStandart.com/table">    <catName:cat>Кот</catName:cat>    <catName:name>Борис</catName:name>  </catName:table></root>
          <root>

<root>
  <classic:table xmlns:classic="https://www.w3.org/TR/html51">
    <classic:tr>
      <classic:th>Заголовок 1</classic:th>
      <classic:th>Заголовок 2</classic:th>
    </classic:tr>
    <classic:tr>
      <classic:td>Элемент 1</classic:td>
      <classic:td>Элемент 2</classic:td>
    </classic:tr>
  </classic:table>

  <catName:table xmlns:catName="https://catNameStandart.com/table">
    <catName:cat>Кот</catName:cat>
    <catName:name>Борис</catName:name>
  </catName:table>
</root>

        
        
          
        
      

Можно перенести все объявления пространств имён в корневой элемент. В нашем случае это будет так:

        
          
          <root xmlns:classic="https://www.w3.org/TR/html51/" xmlns:catName="https://catNameStandart.com/table">  <!-- код с таблицами как в примере выше, но без атрибутов xmlns в тегах table --></root>
          <root xmlns:classic="https://www.w3.org/TR/html51/" xmlns:catName="https://catNameStandart.com/table">
  <!-- код с таблицами как в примере выше, но без атрибутов xmlns в тегах table -->
</root>

        
        
          
        
      

Важное замечание на примере SVG. Если отдать браузеру SVG-файл без атрибута xmlns, то он его не отобразит.

У каждого приложения может быть свой вариант обработки конфликтов: либо сообщение об ошибке, либо игнорирование данных, которые оно не может обработать. В любом случае это приведёт к проблемам, поэтому стоит внимательно следить за xmlns.

На практике

Скопировано

Алёна Дьячковская советует

Скопировано

XML vs HTML vs JSON

Скопировано

XML

Скопировано
  • Хорошо структурированный формат легко читать и писать из программ.
  • Теги XML не определены заранее. Их необходимо определить самостоятельно.
  • XML был разработан для передачи данных из API, а не для отображения этих данных.
  • XML - это расширяемый язык разметки, похожий на HTML.
  • Код разметки XML легко понять человеку.

HTML

Скопировано
  • Это простой язык разметки, который выводится в браузерах со стилями по умолчанию.
  • Поддерживает переходы между документами с помощью гиперссылок
  • Достаточно обширный, чтобы обеспечить поддержку встраивания мультимедиа в документы. Для XML такой возможности нет.
  • В отличие от XML и JSON, браузеры при обработке прощают ошибки и чинят их стандартным образом.

JSON

Скопировано
  • Популярнее XML, поддерживается всеми современными бэкендами.
  • Есть типы данных.
  • Легко использовать в JavaScript, так как не нужен парсинг.
  • Легко создавать и управлять с помощью JavaScript.

Преимущества использования XML

Скопировано
  • Делает документы совместимыми между системами и приложениями. С помощью XML можно быстро обмениваться данными между разными платформами.
  • XML отделяет данные от HTML. Для этого можно хранить данные в XML файле и получать новые и динамические значения в HTML-файле.
  • XML упрощает процесс смены платформы. Так как XML является текстовым форматом данных, можно спокойно менять платформу без лишних заморочек.

Недостатки XML

Скопировано
  • XML часто необходимо парсить чтобы извлечь данные.
  • Нет встроенной поддержки типов данных.
  • Пространство имён сложно реализовывать и использовать.
  • Многословнее чем JSON. Придётся писать много открывающих и закрывающих тегов.

Пример

Скопировано

Если мы пишем сайт с фильмографией, то нам необходимо знать название, год производства, жанры и бюджет картины. Ниже представлен пример набора информации о фильме.

        
          
          <?xml version="1.0" encoding="UTF-8"?><film>  <name>Шрэк</name>  <description>    мультфильм, фэнтези, комедия, приключения, семейный  </description>  <creationYear>2001</creationYear>  <budget>60 000 000 $</budget></film>
          <?xml version="1.0" encoding="UTF-8"?>
<film>
  <name>Шрэк</name>
  <description>
    мультфильм, фэнтези, комедия, приключения, семейный
  </description>
  <creationYear>2001</creationYear>
  <budget>60 000 000 $</budget>
</film>