Привет! Сегодня мы познакомимся с еще одним форматом данных, который называется XML.
Если коротко: XML это текстовый формат для описания данных. Данные в нем размечаются тегами в угловых скобках, теги вкладываются друг в друга и образуют дерево, а у каждого тега могут быть атрибуты. Сам по себе XML ничего не делает и никак данные не отображает: он их только описывает, а читает и обрабатывает уже программа, например на Java.
Это очень важная тема. В работе над настоящими Java-приложениями ты почти наверняка столкнешься с задачами, связанными с XML. Этот формат используется в Java-разработке практически повсеместно (зачем именно, узнаем ниже), поэтому рекомендую тебе читать лекцию не «по диагонали», а разобраться во всем досконально и заодно изучить
дополнительные материалы по XML :) Это время точно не будет потрачено впустую.
Итак, начнем с простого: «что» и «зачем»!
Кратко
- XML это язык разметки для хранения и передачи данных, а не язык программирования: сам он ничего не выполняет.
- Все держится на тегах: каждому открывающему нужен закрывающий, теги вкладываются друг в друга и образуют дерево с одним корневым тегом.
- У тега бывают атрибуты, они уточняют данные:
<price currency="US dollar">.
- Первая строка файла, пролог
<?xml version="1.0" encoding="UTF-8"?>, задает версию и кодировку. Она не обязательна, но с текстом на разных языках выручает.
- От HTML отличается тем, что теги не заданы заранее: называть их можно как угодно, а отображением данных XML не занимается вовсе.
- Одинаковые имена тегов из разных источников разводят префиксами и пространствами имен (
xmlns), а уникальность имени обычно обеспечивают через URI.
Что такое XML?
XML расшифровывается как eXtensible Markup Language, то есть «расширяемый язык разметки».
Один из языков разметки тебе, возможно, уже знаком: ты слышал об HTML, с помощью которого создаются веб-страницы :)
![Две розовые бирки на веревочках: на левой нарисованы ноги в кроссовках с подписью <>MAN</>, на правой ноги в туфлях на каблуке с подписью <>WOMAN</>]()
HTML и XML похожи даже внешне:
HTML 1
<h1>title</h1>
<p>paragraph</p>
<p>paragraph</p>
|
XML 1
<headline>title</headline>
<paragraph>paragraph</paragraph>
<paragraph>paragraph</paragraph>
|
HTML 2
<h1>title</h1>
<p>paragraph</p>
<p>paragraph</p>
|
XML 2
<chief>title</chief>
<paragraph>paragraph</paragraph>
<paragraph>paragraph</paragraph>
|
Иными словами, XML это язык для описания данных.
Зачем нужен XML?
XML изначально придумали для более удобного хранения и передачи данных, в том числе через Интернет.
У него есть ряд преимуществ, которые позволяют успешно справляться с этой задачей.
Во-первых, он легко читается и человеком, и компьютером.
Думаю, ты без труда поймешь, что описывает этот xml-файл:
<?xml version="1.0" encoding="UTF-8"?>
<book>
<title>Harry Potter and the Philosopher’s Stone</title>
<author>J. K. Rowling</author>
<year>1997</year>
</book>
Компьютер тоже без труда понимает такой формат.
Во-вторых, поскольку данные хранятся в простом текстовом формате, при их передаче с одного компьютера на другой не возникнет никаких проблем с совместимостью.
Важно понимать, что
XML это не исполняемый код, а язык описания данных. После того, как ты описал данные с помощью XML, тебе нужно написать код (например, на Java), который сможет эти данные отправить/принять/обработать.
Как устроен XML?
Его главная составная часть это теги: вот такие штуки в угловых скобках:
<book>
</book>
Теги бывают открывающими и закрывающими. У закрывающего есть дополнительный символ “
/”, это видно на примере выше.
Каждому открывающему тегу должен соответствовать закрывающий.
Они показывают, где начинается и где заканчивается описание каждого элемента в файле.
Теги могут быть вложенными!
В нашем примере с книгой у тега <
book> есть 3 вложенных тега: <
title>, <
author> и <
year>.
Это не ограничивается одним уровнем: у вложенных тегов могут быть свои вложенные теги, и т. д. Такая конструкция называется деревом тегов.
Давай рассмотрим дерево на примере XML-файла с описанием автосалона:
<?xml version="1.0" encoding="UTF-8"?>
<carstore>
<car category="truck">
<model lang="en">Scania R 770</model>
<year>2005</year>
<price currency="US dollar">200000.00</price>
</car>
<car category="sedan">
<model lang="en">Ford Focus</model>
<year>2012</year>
<price currency="US dollar">20000.00</price>
</car>
<car category="sport">
<model lang="en">Ferrari 360 Spider</model>
<year>2018</year>
<price currency="US dollar">150000.00</price>
</car>
</carstore>
Здесь у нас есть тег верхнего уровня <
carstore>. Его еще называют «root», то есть корневой тег.
У <carstore> дочерние теги одного вида, <car>, в примере их три. У <car>, в свою очередь, тоже есть 3 своих дочерних тега: <model>, <year> и <price>.
Каждый тег может иметь атрибуты, то есть дополнительную важную информацию. В нашем примере у тега <model> есть атрибут «lang», то есть язык, на котором написано название модели:
<model lang="en">Scania R 770</model>
Так мы можем указать, что название написано на английском языке.
У нашего тега <price> (цена) есть атрибут «currency», то есть «валюта».
<price currency="US dollar">150000.00</price>
Так мы можем указать, что цена за машину указана в американских долларах.
Таким образом,
у XML есть «самоописывающий» синтаксис. Ты можешь добавить любую нужную тебе информацию для описания данных.
Также в начало файла можно добавить строку с указанием версии XML и кодировки, в которой записаны данные.
Она называется «
prolog» и выглядит вот так:
<?xml version="1.0" encoding="UTF-8"?>
Мы применяем
XML версии 1.0 и кодировку UTF-8. Это не обязательно, но может пригодиться, если ты, например, используешь в своем файле текст на разных языках.
Мы упомянули о том, что XML переводится как «расширяемый язык разметки», но что значит «расширяемый»?
Это означает, что он отлично приспособлен для создания новых версий твоих объектов и файлов.
К примеру, мы хотим, чтобы в нашем автосалоне начали продавать еще и мотоциклы!
При этом в программе нам нужно поддерживать обе версии <carstore>: и старую (без мотоциклов), и новую.
Вот наша старая версия:
<?xml version="1.0" encoding="UTF-8"?>
<carstore>
<car category="truck">
<model lang="en">Scania R 770</model>
<year>2005</year>
<price currency="US dollar">200000.00</price>
</car>
<car category="sedan">
<model lang="en">Ford Focus</model>
<year>2012</year>
<price currency="US dollar">20000.00</price>
</car>
<car category="sport">
<model lang="en">Ferrari 360 Spider</model>
<year>2018</year>
<price currency="US dollar">150000.00</price>
</car>
</carstore>
А вот новая, расширенная:
<?xml version="1.0" encoding="UTF-8"?>
<carstore>
<car category="truck">
<model lang="en">Scania R 770</model>
<year>2005</year>
<price currency="US dollar">200000.00</price>
</car>
<car category="sedan">
<model lang="en">Ford Focus</model>
<year>2012</year>
<price currency="US dollar">20000.00</price>
</car>
<car category="sport">
<model lang="en">Ferrari 360 Spider</model>
<year>2018</year>
<price currency="US dollar">150000.00</price>
</car>
<motorcycle>
<model lang="en">Yamaha YZF-R6</model>
<year>2018</year>
<price currency="Russian Ruble">1000000.00</price>
<owner>Vasia</owner>
</motorcycle>
<motorcycle>
<model lang="en">Harley Davidson Sportster 1200</model>
<year>2011</year>
<price currency="Euro">15000.00</price>
<owner>Petia</owner>
</motorcycle>
</carstore>
Вот так легко и просто мы добавили описание мотоциклов в наш файл :)
При этом нам совершенно не нужно задавать для мотоциклов те же дочерние теги, что и для машин. Обрати внимание, что у мотоциклов, в отличие от машин, есть элемент <owner>, то есть владелец.
Это никак не помешает компьютеру (да и человеку тоже) прочитать данные.
Отличия XML от HTML
Мы уже сказали, что XML и HTML внешне очень похожи. Поэтому, очень важно знать, чем они отличаются.
Во-первых, они используются для разных целей.
HTML нужен для разметки веб-страниц. Например, если тебе нужно создать веб-сайт, с помощью HTML ты сможешь указать: «Меню должно быть в верхнем правом углу. В нем должны быть такие-то кнопки». Иными словами, задача HTML это отображение данных.
XML нужен для хранения и передачи информации в удобном для человека и компьютера виде. Этот формат не содержит никаких указаний на то, как эти данные нужно отображать: это зависит от кода самой программы.
Во-вторых, у них есть основное техническое отличие. Теги HTML являются заранее заданными («predefined»).
Иными словами, для создания заголовка (например, большой надписи в начале страницы) в HTML используются только теги <h1></h1> (для заголовков поменьше <h2></h2>,<h3></h3>). Не получится создать заголовки в HTML, используя теги с другими названиями.
XML не использует заранее заданные теги. Ты можешь давать тегам любые названия, какие захочешь: <header>, <title>, <idontknow2121>.
Коротко все различия выглядят так:
|
HTML |
XML |
| Задача |
Отобразить данные: как страница выглядит в браузере |
Описать данные, чтобы их можно было сохранить и передать |
| Теги |
Заданы заранее, свои придумать нельзя |
Любые, какие нужны: <carstore>, <idontknow2121> |
| Внешний вид данных |
Задается самой разметкой |
Не задается никак, это забота программы, которая читает файл |
| Незакрытый тег |
Браузер, скорее всего, отрисует страницу и так |
Нарушение разметки это фатальная ошибка, документ не обработается |
Разрешение конфликтов
Свобода, которую предоставляет XML, может привести и к некоторым проблемам.
К примеру, одна и та же сущность (например, машина) может использоваться программой в разных целях.
К примеру, у нас есть XML-файл, в котором описаны машины. Однако, наши программисты не договорились заранее между собой. И теперь, помимо данных реальных автомобилей, в наши xml попадают еще и данные игрушечных моделей! Более того, у них одинаковые атрибуты.
В нашу программу приходит вот такой XML-файл. Как же нам отличить настоящую машину от игрушечной модельки?
<?xml version="1.0" encoding="UTF-8"?>
<carstore>
<car category="truck">
<model lang="en">Scania R 770</model>
<year>2005</year>
<price currency="US dollar">200000.00</price>
</car>
<car category="sedan">
<model lang="en">Ford Focus</model>
<year>2012</year>
<price currency="US dollar">100.00</price>
</car>
</carstore>
Здесь нам помогут префиксы и пространства имен.
Чтобы отделять в нашей программе игрушечные машины от настоящих (да и вообще любые игрушечные вещи от их реальных прототипов), мы вводим два префикса: «real» и «toy».
<real:car category="truck">
<model lang="en">Scania R 770</model>
<year>2005</year>
<price currency="US dollar">200000.00</price>
</real:car>
<toy:car category="sedan">
<model lang="en">Ford Focus</model>
<year>2012</year>
<price currency="US dollar">100.00</price>
</toy:car>
Теперь наша программа сможет различить сущности! Все, что имеет префикс toy, будет отнесено к игрушкам :)
Однако, мы пока не закончили. Чтобы использовать префиксы, нам надо зарегистрировать каждый из них в качестве пространства имен (namespace).
Ну, на самом деле, «зарегистрировать» это громко сказано :) Достаточно просто придумать уникальное имя для каждого из них.
Это как с классами: у класса есть короткое имя (
Cat) и полное имя с указанием всех пакетов (
zoo.animals.Cat)
Для создания уникальных имен namespace обычно используют URI. Иногда сюда подставляют адрес в Сети, где подробно описаны функции и предназначение этого пространства имен.
Но это не обязательно должен быть действующий интернет-адрес. Очень часто на проектах используют просто URI-подобные строки, которые помогают отследить иерархию пространств имен.
Вот пример:
<?xml version="1.0" encoding="UTF-8"?>
<carstore xmlns:real="http://testproject.developersgroup1.companyname/department2/namespaces/real"
xmlns:toy="http://testproject.developersgroup1.companyname/department2/namespaces/toy">
<real:car category="truck">
<model lang="en">Scania R 770</model>
<year>2005</year>
<price currency="US dollar">200000.00</price>
</real:car>
<toy:car category="sedan">
<model lang="en">Ford Focus</model>
<year>2012</year>
<price currency="US dollar">100.00</price>
</toy:car>
</carstore>
Конечно, в Сети нет никакого сайта по адресу
http://testproject.developersgroup1.companyname/department2/namespaces/real
Но тут есть полезная информация: за создание пространства имен «real» отвечает группа разработчиков «developersgroup1» из отдела «department2». Если нужно будет внести новые имена, или обсудить с ними возможные конфликты, мы знаем куда обратиться.
Иногда в качестве уникального имени для namespace используют реальный адрес в Сети с описанием этого пространства имен. Например, если это большая компания, и ее проект будет использоваться миллионами людей по всему миру. Но это делается далеко не всегда: на
Stackoverflow есть обсуждение этого вопроса.
В принципе, требование использовать URI в качестве имен для namespace не является строгим: можно и просто рандомные строки.
Такой вариант тоже будет работать:
xmlns:real="nvjneasiognipni4435t9i4gpojrmeg"
Но у использования URI есть ряд преимуществ. Подробнее об этом ты можешь почитать
вот тут.
Основные стандарты XML
Стандарты XML это набор расширений, которые придают xml-файлам дополнительные возможности.
XML имеет очень много стандартов, но мы лишь посмотрим на самые важные из них, и узнаем, что они позволяют делать
AJAX
Строго говоря, это не стандарт XML, а прием веб-разработки, который попал в этот список за компанию. AJAX это когда страница подгружает данные с сервера и обновляет себя, не перезагружаясь целиком! Звучит круто? :) Аббревиатура расшифровывается как Asynchronous JavaScript and XML, но XML остался в ней по историческим причинам: сегодня по такой схеме почти всегда возят JSON. Определение и примеры есть
в глоссарии MDN.
XSLT
Позволяет преобразовывать XML-текст в другие форматы. Например, используя XSLT, ты можешь преобразовать XML в HTML! Задача XML, как мы уже говорили, это описание данных, а не отображение. Но с использованием XSLT мы можем обойти это ограничение!
Вот здесь лежит документация MDN по XSLT: описание элементов преобразования и примеры того, как это работает :)
XML DOM
Позволяет получать, изменять, добавлять или удалять отдельные элементы из XML-файла.
Вот небольшой пример как это работает. У нас есть файл books.xml:
<bookstore>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
</bookstore>
В нем две книги. У книг есть такой элемент как заголовок, <title>.
А вот тут мы при помощи JavaScript можем получить из нашего XML-файла все заголовки книг и вывести первый из них в консоль:
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myFunction(this);
}
};
xhttp.open("GET", "books.xml", true);
xhttp.send();
function myFunction(xml) {
var xmlDoc = xml.responseXML;
document.getElementById("demo").innerHTML =
xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue;
}
</script>
</body>
</html>
Пример рабочий, но написан по старой моде:
XMLHttpRequest и
var сегодня заменяют на
fetch(), о чем прямо говорит MDN. Логика при этом остается той же: получить файл, разобрать его как XML, достать нужный тег. Про разбор XML в браузере есть
отдельная статья MDN :)
DTD (document type definition)
Позволяет определить список разрешенных элементов для какой-то сущности в XML-файле.
К примеру, мы работаем над сайтом книжного магазина, и все команды разработчиков договорились, что для элемента book в XML-файлах должны быть указаны только атрибуты title, author и year.
Но как нам защитить себя от невнимательности?
Очень легко!
<?xml version="1.0"?>
<!DOCTYPE book [
<!ELEMENT book (title,author,year)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT year (#PCDATA)>
]>
<book>
<title>The Lord of The Rings</title>
<author>John R.R. Tolkien</author>
<year>1954</year>
</book>
Здесь мы определили список допустимых атрибутов для <book>. Попробуй добавить туда новый элемент, и сразу получишь ошибку!
<book>
<title>The Lord of The Rings</title>
<author>John R.R. Tolkien</author>
<year>1954</year>
<mainhero>Frodo Baggins</mainhero>
</book>
Ошибка! “Element mainhero is not allowed here”
Есть и много других XML-стандартов. Ознакомиться с каждым из них можно на
сайте W3C: там собраны спецификации всего семейства XML, от XML Schema до XPath и XQuery.
Да и вообще, если тебе нужна информация по XML, там можно найти практически все :)
Ну а наша лекция на этом подошла к концу.
Настало время вернуться к задачам! :)
До встречи!
Вопросы и ответы
Что такое XML простыми словами?
Это текстовый формат для описания данных. Название расшифровывается как eXtensible Markup Language, то есть расширяемый язык разметки. Данные размечаются парными тегами в угловых скобках, теги вкладываются друг в друга и образуют дерево. XML не программа и не язык программирования: он ничего не выполняет и ничего не рисует, он только хранит данные в виде, понятном и человеку, и машине.
Чем XML отличается от HTML?
Целью и свободой в именах тегов. HTML нужен, чтобы браузер отобразил страницу, и его теги заданы заранее: заголовок это
<h1>, абзац это
<p>, придумать свои нельзя. XML нужен, чтобы описать данные, и теги в нем называют как удобно:
<carstore>,
<price>, что угодно. Про внешний вид XML не знает ничего, это забота программы, которая файл читает.
Что такое пролог в XML и обязателен ли он?
Пролог это первая строка файла вида
<?xml version="1.0" encoding="UTF-8"?>. Она сообщает версию XML и кодировку, в которой записаны данные. Строка не обязательна, файл будет работать и без нее, но с ней надежнее: если в данных встречается текст на разных языках, явно указанная кодировка избавляет от проблем с нечитаемыми символами.
Зачем нужны пространства имен (namespace) в XML?
Чтобы одинаковые имена тегов из разных источников не путались между собой. Если в один файл попадают данные о настоящих машинах и об игрушечных моделях, теги
<car> будут выглядеть одинаково. Решение это префикс:
<real:car> и
<toy:car>. Каждый префикс объявляют через атрибут
xmlns, а в качестве уникального имени обычно берут URI, причем сайта по этому адресу может и не существовать: важна только уникальность строки.
Что такое DTD и зачем проверять структуру XML?
DTD (document type definition) это описание того, какие элементы разрешены внутри тега и в каком порядке. Если команда договорилась, что у
<book> бывают только
<title>,
<author> и
<year>, то DTD превращает эту договоренность в правило: лишний элемент вызовет ошибку сразу, а не через месяц в чужом коде. Кроме DTD для той же задачи используют схемы XSD, они умеют описывать еще и типы данных.
Чем XML отличается от JSON и что выбрать?
XML описывает данные тегами и умеет то, чего у JSON нет: атрибуты, пространства имен, комментарии, проверку структуры через DTD или XSD, преобразование через XSLT. JSON проще и компактнее, у него нет закрывающих тегов и он ложится один в один на объекты и массивы. Поэтому веб-API сегодня почти всегда отдают JSON, а XML остается там, где важна строгая схема и сложная структура: конфигурации, обмен документами, корпоративные интеграции. В Java с XML встречаешься постоянно хотя бы потому, что на нем написаны файлы сборки Maven.
Читайте также
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ