XML
XML (англ. eXtensible Markup Language) расширяемый язык разметки | |
---|---|
Расширение | .xml |
MIME-тип | application/xml[1], text/xml[2] (deprecated in an expired draft)[3] |
Разработчик | Консорциум Всемирной паутины |
Опубликован | 1998 |
Тип формата | язык разметки |
Расширен из | SGML |
Развит в | XHTML, RSS, Atom, KML, SVG и множество других форматов |
Стандарт(ы) | 1.0 (Fifth Edition), 26 ноября 2008 года[4] 1.1 (Second Edition), 16 августа 2006 года[5] |
Открытый формат? | да |
Сайт | w3.org/XML (англ.) |
Медиафайлы на Викискладе |
XML (МФА: [ˌeks.emˈel], аббр. от англ. eXtensible Markup Language) — «расширяемый язык разметки». Рекомендован Консорциумом Всемирной паутины (W3C). Спецификация XML описывает XML-документы и частично описывает поведение XML-процессоров (программ, читающих XML-документы и обеспечивающих доступ к их содержимому). XML разрабатывался как язык с простым формальным синтаксисом, удобный для создания и обработки документов как программами, так и человеком, с акцентом на использование в Интернете. Язык называется расширяемым, поскольку он не фиксирует разметку, используемую в документах: разработчик волен создать разметку в соответствии с потребностями к конкретной области, будучи ограниченным лишь синтаксическими правилами языка. Расширение XML — это конкретная грамматика, созданная на базе XML и представленная словарём тегов и их атрибутов, а также набором правил, определяющих, какие атрибуты и элементы могут входить в состав других элементов. Сочетание простого формального синтаксиса, удобства для человека, расширяемости, а также базирование на кодировках Юникод для представления содержания документов привело к широкому использованию как, собственно, XML, так и множества производных специализированных языков на базе XML в самых разнообразных программных средствах.
XML является подмножеством SGML.
Файлы в формате XML используется при проектировании структуры программ, в частности, концептуальных карт и диаграмм связей.
Язык XML
[править | править код]Спецификация XML описывает язык и ряд вопросов, касающихся кодировки и обработки документов. Материал этой секции представляет собой сокращённое изложение описания языка в Спецификации XML, адаптированное для настоящей статьи.
Нормативным считается английский вариант документа, поэтому основные термины приводятся с их английскими оригиналами.
Перевод основных терминов в основном следует доступному в интернете переводу Спецификации на русский язык, исключение составляют термины tag и declaration. Для термина tag здесь используется перевод тег. Для термина declaration отдано предпочтение распространённому переводу объявление (против также распространённой кальки декларация).
В литературе и интернете могут встречаться и иные переводы основных терминов.
Физическая и логическая структуры документа
[править | править код]С физической точки зрения документ состоит из сущностей (англ. entities), из которых каждая может ссылаться на другую сущность. Единственный корневой элемент — документная сущность. Содержание сущностей — символы.
С логической точки зрения документ состоит из комментариев (англ. comments), объявлений (англ. declarations), элементов (англ. elements), ссылок на сущности (англ. character references) и инструкций обработки (англ. processing instructions). Всё это в документе структуризуется разметкой (англ. markup).
Физическая структура
[править | править код]Сущность — мельчайшая часть в документе. Все сущности что-нибудь содержат, и у всех них есть имя (существуют исключения, напр. документная сущность). Проще говоря, термин «сущность» описывает «сущую вещь», «что-то»[6].
Документ состоит из сущностей, содержание которых — символы. Все символы разделены на два типа: символы данных (англ. character data) и символы разметки. К разметке относятся:
- теги (англ. tags) <- обозначают границы элементов
- объявления и инструкции обработки, включая их атрибуты (англ. attributes)
- ссылки на сущности
- комментарии
- а также последовательности символов, обрамляющие секции «CDATA»
Часть документа, не принадлежащая разметке, составляет символьные данные документа.
Логическая структура
[править | править код]Все составляющие части документа обобщаются в пролог и корневой элемент. Корневой элемент — обязательная часть документа, составляющая всю его суть (пролог, вообще говоря, может отсутствовать). Корневой элемент может включать (а может не включать) вложенные в него элементы, символьные данные и комментарии. Вложенные в корневой элемент элементы, в свою очередь, могут включать вложенные в них элементы, символьные данные и комментарии, и так далее. Пролог может включать объявления, инструкции обработки, комментарии. Его следует начинать с объявления XML, хотя в определённой ситуации допускается отсутствие этого объявления.
Элементы документа должны быть правильно вложены: любой элемент, начинающийся внутри другого элемента (то есть любой элемент документа, кроме корневого), должен заканчиваться внутри элемента, в котором он начался. Символьные данные могут встречаться внутри элементов как непосредственно так и в специальных секциях «CDATA». Объявления, инструкции обработки и элементы могут иметь связанные с ними атрибуты. Атрибуты используются для связывания с логической единицей текста пар имя-значение.
Символы разметки
[править | править код]Разметка всегда начинается символом <
и заканчивается символом >
.
Наряду с символами <
и >
, специальную роль для разметки играет также символ &
. Угловые скобки обозначают границы элементов, инструкций обработки и некоторых других последовательностей. Амперсанд позволяет выполнить замену текста при помощи сущностей (англ. entities)[6].
Решение проблемы неоднозначности разметки
[править | править код]Употребление разметочных символов в символьных данных затрудняет распознавание конструкций разметки и может создать проблему неоднозначности структуры. В XML эта проблема решается следующим образом: <, > и & не могут присутствовать в символьных данных и в значениях атрибутов в их непосредственном виде, для их представления в этих случаях зарезервированы специальные сущности:
Символ | Замена |
---|---|
< | < |
> | > |
& | & |
Кроме того, для употребления апострофов и кавычек внутри значений атрибутов используются следующие сущности:
' | ' |
" | " |
Правило замены разметочных символов на их обозначающие сущности не распространяется на символьные данные в секциях «CDATA», зато выполняется во всех остальных местах документа.
Числовые ссылки на символы
[править | править код]Числовые ссылки на символы указывают кодовую позицию символа в наборе символов документа. Числовые ссылки на символы могут принимать две формы[7]:
- синтаксис «&#D;», где D — десятичное число;
- синтаксис «&#xH;» или «&#XH;», где H — шестнадцатеричное число (шестнадцатеричные числа в числовых символьных ссылках не чувствительны к регистру).
Примеры числовых ссылок на символы:
- å — (в десятичной форме) представляет букву «а» с маленьким кружком над ней (используется, например, в норвежском языке);
- å — (в шестнадцатеричном) представляет собой тот же символ;
- å — (в шестнадцатеричном) также представляет тот же символ;
- И — (в десятичной форме) представляет заглавную букву кириллицы «I»;
- 水 — (в шестнадцатеричном) представляет китайский иероглиф «вода»;
Имена
[править | править код]В языке XML все имена должны начинаться с буквы, символа подчёркивания (_) и продолжаться только допустимыми для имён символами, а именно: они могут содержать только буквы, входящие в секцию букв кодировки Unicode, арабские цифры, дефисы, знаки подчёркивания, точки. Так как буквы не ограничены исключительно символами ASCII, то в именах можно использовать буквы из любого языка.
Пролог
[править | править код]Объявление XML
[править | править код]Объявление XML указывает версию языка, на которой написан документ. Поскольку интерпретация содержимого документа зависит от версии языка, то Спецификация предписывает начинать документ с объявления XML. В первой (1.0) версии языка использование объявления не было обязательным, в последующих версиях оно обязательно. Таким образом, версия языка определяется из объявления, и если объявление отсутствует, то принимается версия 1.0.
Кроме версии XML объявление может также содержать информацию о кодировке документа и «оставаться ли документу со своим собственным DTD, или с подключённым».
Пример:
<?xml version="1.1" encoding="UTF-8" ?>
или:
<?xml version="1.0" encoding="windows-1251"?>
Во всех этих примерах отсутствовал атрибут «standalone», который как раз и определяет, подключить ли документу описания разметки извне. По умолчанию он равен «no»:
<?xml version="1.0" encoding="windows-1251" standalone="no"?>
если XML-документ ссылается на другие DTD-файлы, которые описывают, что документ может содержать, вы должны указать standalone="no"
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
если XML-документ не ссылается на другие файлы и будет пользоваться своим DTD, вы должны указать standalone="yes"
Объявление типа документа
[править | править код]Для объявления типа документа существует специальная инструкция !DOCTYPE
. Она позволяет задать при помощи языка DTD, какие в документ входят элементы, каковы их атрибуты, какие сущности могут использоваться и кое-что ещё.
Например, вот корректный документ:
<?xml version="1.0"?> <greeting>Hello, world!</greeting>
В нём есть корневой элемент <greeting>Hello, world!</greeting>
, и с логической точки зрения документ существует. Однако он недействителен (англ. not valid)[8].
При помощи Объявления типа документа (DTD) возможно описывать его содержание и логическую структуру, а также связывать с определённым элементом пару «имя — значение». Вот как выглядит пролог в записи Бэкуса — Наура[9]:
prolog ::= XMLDecl? Misc* (doctypedecl Misc*)? XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>' VersionInfo ::= S 'version' Eq ("'" VersionNum "'" | '"' VersionNum '"') Eq ::= S? '=' S? VersionNum ::= '1.' [0-9]+ Misc ::= Comment | PI | S doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? ('[' intSubset ']' S?)? '>' DeclSep ::= PEReference | S intSubset ::= (markupdecl | DeclSep)* markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment extSubset ::= TextDecl? extSubsetDecl extSubsetDecl ::= ( markupdecl | conditionalSect | DeclSep)*
После XML-объявления могут следовать комментарии, инструкции обработки или же пустые пространства[10], но затем идёт Объявления типа документа, где «Name» — имя корневого тега, «ExternalID» — внешний идентификатор, а «intSubset» — объявление разметки или же ссылка на сущность. Как гласит спецификация, если внешний идентификатор объявляется вместе с внутренним объявлением, то последнее идёт перед первым[11].
Например:
<?xml version="1.0"?> <!DOCTYPE greeting SYSTEM "hello.dtd"> <greeting>Hello, world!</greeting>
Здесь «SYSTEM "hello.dtd"
» — внешний идентификатор: адрес «hello.dtd» позволяет задействовать данные в документе «hello.dtd» как объявления разметки.
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE greeting [ <!ELEMENT greeting (#PCDATA)> ]> <greeting>Hello, world!</greeting>
Здесь же разметка была объявлена локально в инструкции !DOCTYPE
.
Инструкция обработки
[править | править код]Инструкции обработки (англ. processing instruction, PI), позволяют размещать в документе инструкции для приложений. В следующем примере показана инструкция обработки xml-stylesheet, передающая xml-stylesheet-приложению (например, браузеру) инструкции в файле my-style.css посредством атрибута href:
<?xml-stylesheet type="text/css" href="my-style.css"?>
Комментарий
[править | править код]Комментарии (англ. comment) не относятся к символьным данным документа. Комментарий начинается последовательностью «<!--» и заканчивается последовательностью «-->», внутри не может встречаться комбинация символов «--». Символ & не используется внутри комментария в качестве разметки.
Пример:
<!-- это комментарий -->
Корневой элемент
[править | править код]Элемент и его разметка
[править | править код]Элемент (англ. element) является понятием логической структуры документа. Каждый документ содержит один или несколько элементов. Границы элементов представлены начальным и конечным тегами. Имя элемента в начальном и конечном тегах элемента должно совпадать. Элемент может быть также представлен тегом пустого элемента, то есть не включающего в себя другие элементы и символьные данные.
Тег (англ. tag) — конструкция разметки, которая содержит имя элемента.
Начальный тег: <element1>
Конечный тег: </element1>
Тег пустого элемента: <empty_element1 />
В элементе атрибуты могут использоваться только в начальном теге и теге пустого элемента.
Пример кулинарного рецепта, размеченного с помощью XML:
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE recipe> <recipe name="хлеб" preptime="5min" cooktime="180min"> <title> Простой хлеб </title> <composition> <ingredient amount="3" unit="стакан">Мука</ingredient> <ingredient amount="0.25" unit="грамм">Дрожжи</ingredient> <ingredient amount="1.5" unit="стакан">Тёплая вода</ingredient> </composition> <instructions> <step> Смешать все ингредиенты и тщательно замесить. </step> <step> Закрыть тканью и оставить на один час в тёплом помещении. </step> <!-- <step> Почитать вчерашнюю газету. </step> - это сомнительный шаг... --> <step> Замесить ещё раз, положить на противень и поставить в духовку. </step> </instructions> </recipe>
Секция CDATA
[править | править код]Секция CDATA не является логической единицей текста. Секция может встречаться в любом месте документа, где синтаксис позволяет размещать символьные данные. Секция начинается <![CDATA[
и завершается ]]>
. Между этой разметкой находятся символьные данные; символьные данные при этом включают символы < > &
в их непосредственной форме.
Корректный документ
[править | править код]Корректный (англ. well-formed) документ соответствует всем общим правилам синтаксиса XML, применимым к любому XML-документу: правильная структура документа, совпадение имен в начальном и конечном теге элемента и т. п. Документ, который неправильно построен, не может считаться документом XML.
Пространства имён
[править | править код]Пример документа:
<?xml version="1.0" encoding="UTF-8"?> <!-- login screen --> <edsscript> <sequence name="start"> <action cmd="triggeron"> btn* </action> <action cmd="triggeron"> msg_generic </action> <action cmd="disablenbb"> all </action> <action cmd="setscrtext"> @@Sisteme Giriş@@ </action> <action cmd="enablenbb"> forward,mainmenu </action> <action cmd="switchmsgtarget"> LOGIN_DLG </action> <action cmd="sendmsg"> start </action> <action cmd="jump"> step2 </action> </sequence> <sequence name="step2"> <action cmd="waittrigger"> btnforward </action> <action cmd="triggeron"> login* </action> <action cmd="disablenbb"> all </action> <action cmd="sendmsg"> check </action> </sequence> <trigger name="login_succeded"> <condition type="appmsg"> login_succeeded </condition> <sequence> <action cmd="endscript" /> </sequence> </trigger> <trigger name="login_unknownuser"> <condition type="appmsg"> login_unknownuser </condition> <sequence name="login_unknownuser"> <action cmd="disablenbb"> all </action> <action cmd="setscrtext"> @@Hata@@ </action> <action cmd="showhtml"> generic_neg.htm,@@Yanlış kullanıcı ismi@@,@@Lütfen kullanıcı ismini doğru giriniz.@@ </action> <action cmd="enablenbb"> back </action> <action cmd="waittrigger"> btnback </action> <action cmd="jump"> start </action> </sequence> </trigger> <trigger name="login_incorrectpwd"> <condition type="appmsg"> login_incorrectpwd </condition> <sequence name="login_incorrectpwd"> <action cmd="disablenbb"> all </action> <action cmd="setscrtext"> @@Hata@@ </action> <action cmd="showhtml"> generic_neg.htm,@@Hatalı parola@@,@@Lütfen parolanızı doğru giriniz.@@ </action> <action cmd="enablenbb"> back </action> <action cmd="waittrigger"> btnback </action> <action cmd="jump"> start </action> </sequence> </trigger> <!-- generic triggers --> <trigger name="btnback"> <condition type="buttonclick"> back </condition> <sequence name="btnback"> <action cmd="triggeron"> btnback </action> </sequence> </trigger> <trigger name="btnforward"> <condition type="buttonclick"> forward </condition> <sequence name="btnforward"> <action cmd="triggeron"> btnforward </action> </sequence> </trigger> <trigger name="btnmainmenu"> <condition type="buttonclick"> mainmenu </condition> <sequence> <action cmd="jumpscript"> <value label="mainmenuscript" scope="local" /> </action> </sequence> </trigger> <trigger name="btnquitapp"> <condition type="buttonclick"> quitapplication </condition> <sequence name="btnquitapp"> <action cmd="callscript"> quitapp.xml </action> <action cmd="jump"> start </action> </sequence> </trigger> <trigger name="error_generic"> <condition type="appmsg"> error* </condition> <sequence> <action cmd="showhtml"> errdsc_null.htm,@@Hata@@ </action> <action cmd="disablenbb"> all </action> <action cmd="enablenbb"> forward </action> <action cmd="waittrigger"> btnforward </action> <action cmd="endscript" /> </sequence> </trigger> <trigger name="msg_generic"> <condition type="appmsg"> msg_generic </condition> <sequence> <action cmd="showhtml"> generic_msg.htm </action> <action cmd="triggeron"> msg_generic </action> </sequence> </trigger> <!-- An unhandled exception is thrown from the hard code side. --> <trigger name="error_hardcodeside"> <condition type="appmsg"> error_hardcodeside </condition> <sequence> <action cmd="triggeroff"> * </action> <action cmd="triggeron"> btnmainmenu </action> <action cmd="triggeron"> btnquitapp </action> <action cmd="disablenbb"> all </action> <action cmd="enablenbb"> mainmenu </action> <action cmd="showhtml"> errdsc_null.htm,Hata, @@İşlem sırasında bir hata meydana geldi.@@ </action> <action cmd="waittrigger"> btnmainmenu </action> </sequence> </trigger> </edsscript>
Регламентация работы с документами: правила, языки, программные интерфейсы
[править | править код]Этот раздел содержит изложение некоторых положений рекомендаций W3C, касающихся работы с документами. Соответствующие рекомендации могут относиться как к документам XML, так и к более широкому классу документов. Ссылки, как правило, даются на средства работы с документами, рекомендованные W3C.
Кодировка документов
[править | править код]Спецификация требует, чтобы обрабатывающие программы поддерживали по крайней мере две кодировки Юникод: UTF-8 и UTF-16.
XML-процессор и приложение
[править | править код]Спецификация XML определяет понятия XML-процессор и приложение. XML-процессор (парсер) — программа, анализирующая разметку и передающая информацию о структуре документа другой программе — приложению.
Спецификация XML налагает определённые требования на процессор, не касаясь требований к приложению.
Действительный документ. Проверяющие и непроверяющие процессоры
[править | править код]Документ является действительным, если с ним связано определение типа документа и если этот документ отвечает представленным в определении типа документа ограничениям.
XML-процессоры делятся на два класса: проверяющие и непроверяющие.
Проверяющие процессоры проверяют действительность документа и должны сообщать (по выбору пользователя) о нарушении ограничений, сформулированных в определении типа документа.
Непроверяющие процессоры не проверяют действительность документа, но обязанности по предварительной обработке документа, упомянутые выше, остаются за ними.
Описание типов документов: языки схем
[править | править код]Для описания типов документов используются языки схем (англ. schema language). Поскольку XML является подмножеством языка SGML, то он унаследовал разработанный для SGML язык Document Type Definition (DTD). Позднее были разработаны и другие языки схем, наиболее известны из которых XML Schema, RELAX NG.
Преобразование документа XML
[править | править код]Для решения задачи преобразования документа XML в другую схему или другой формат предназначен язык XSLT.
Формат для визуализации документа
[править | править код]Для форматированного документа (документа, подготовленного к визуализации) предназначен формат XSL-FO.
Языки запросов
[править | править код]XPath — синтаксис для адресации содержимого документа, представленного в форме дерева. Выражения XPath используются в языке XQuery. Выражения XPath, вообще говоря, могут использоваться в любом контексте, где уместно использовать формальные ссылки на элементы дерева, в частности, в качестве параметров методов интерфейсов доступа к документу.
XQuery — язык программирования, ориентированный на работу с документами.
Чтение XML: три варианта API
[править | править код]В разделе не хватает ссылок на источники (см. рекомендации по поиску). |
Для чтения XML есть три варианта API[12].
Событийный API (event-driven API, push-style API) — XML-процессор читает XML; при определённом событии (появлении открывающего или закрывающего тега, текстовой строки, атрибута) вызывается callback-функция.
- + Расходует мало памяти[12].
- + При обработке огромного XML есть стандартная точка, позволяющая мгновенно остановить обработчик[12].
- − Крайне сложен для прикладного программиста: приходится держать в памяти информацию, в каком месте документа мы находимся.
- + Библиотека проста в программировании.
- − Только последовательный доступ к XML[13], это затрудняет разбор перекрёстных ссылок и «почти правильных» XML с перепутанным порядком элементов.
- − API только для чтения, для записи потребуется другой API[14].
- ± Естественный выбор, когда из огромного XML надо извлечь немного данных[12].
- ± Естественный выбор, когда XML надо преобразовать в структуру предметной отрасли[12].
- Примеры библиотек: SAX, Expat
<?xml version="1.0" encoding="UTF-8" ?> <document> <thing name="A">Alpha</thing> <thing name="B">Bravo</thing> </document>
enum class Place { ROOT, DOCUMENT, THING, N } Place parentPlace[static_cast<int>(Place::N)] = { ROOT, ROOT, DOCUMENT }; class MyEvent : public Xml::Event { private: Place place = Place::ROOT; Thing* currThing = nullptr; public: /// @return true — тег нужен; false — пропустить его и всё, что внутри bool onTagOpen(const std::string& aName) override; void onTagClose() override; void onAttr(const std::string& aName, const std::string& aValue) override; void onText(const std::string& aText) override; } bool MyEvent::onTagOpen(const std::string& aName) { switch (place) { case Place::ROOT: if (aName == "document") { place = Place::DOCUMENT; return true; } break; case Place::DOCUMENT: if (aName == "thing") { place = Place::THING; currThing = &things.emplace_back(); return true; } break; } return false; } void MyEvent::onTagClose() { place = parentPlace[place]; } void MyEvent::onAttr(const std::string& aName, const std::string& aValue) { if (place == Place::THING && aName == "name") currThing->name = aValue; } void MyEvent::onText(const std::string& aText) { if (place == Place::THING) currThing->value = aText; } xml::eventDrivenRead("in.xml", MyEvent());
Потоковый API (также pull-style API) — устроен на манер потоков ввода-вывода. Прикладной код запрашивает у процессора части XML, тот умеет только двигаться по XML вперёд, забывая уже пройденные части.
- + Расходует мало памяти.
- + Информация, в каком месте документа мы находимся, неявно задаётся местом в потоке выполнения. Это серьёзно упрощает работу прикладного программиста[14][15]. На продуманных API объём кода приближается к таковому для DOM.
- − Библиотека сложна в программировании.
- + Позволяет одновременный доступ к двум XML-документам[15].
- − Только последовательный доступ к XML[14], это затрудняет разбор перекрёстных ссылок и «почти правильных» XML с перепутанным порядком элементов.
- − API только для чтения, для записи потребуется другой API. (StAX, хоть относится и к потоковым, содержит отдельный API прямой записи[16].)
- Примеры библиотек: StAX
xml::StreamReader reader("in.xml"); std::string name, value; reader.enterTag("document"); while (reader.getTag("thing") { Thing thing; thing.name = reader.requireStringAttr("name"); reader.enterTag(); thing.value = reader.getText(); reader.leaveTag(); things.emplace_back(std::move(thing)); }
Объектный API (Document Object Model, DOM, «объектная модель документа») — считывает XML и воссоздаёт его в памяти в виде объектной структуры.
- − Расходует много памяти — намного больше, чем сам XML занимает на диске. На pugixml расход памяти втрое и более превышает длину XML.
- + Прост для прикладного программиста.
- + Библиотека проста в программировании.
- + Позволяет произвольный доступ к XML[12]. Это, например, упрощает работу с перекрёстными ссылками. Зачастую удаётся распознать «почти верные» XML с перепутанным порядком тегов.
- + Общий API для чтения и записи[14].
- ± Естественный выбор, когда объектом предметной области является сам XML: в веб-браузере[12], XML-редакторе, в импортёре к программе-локализатору, который извлекает строки из XML произвольной структуры.
- ± Естественный выбор, когда нужно загрузить XML, слегка переработать и сохранить[12][14]. Те части, которые трогать не нужно, не требуют никакого кода.
- Примеры библиотек: JDOM, TinyXML, pugixml
#include <iostream> #include <vector> #include "pugixml.hpp" struct Thing { std::string name, value; }; // Если какая-то сущность pugixml конвертируется в bool как false — выкинуть ошибку! template <class T> inline T need(T&& val, const char* errmsg) { if (!val) throw std::logic_error(errmsg); return std::forward<T>(val); } int main() { std::vector<Thing> things; pugi::xml_document doc; need(doc.load_file("in.xml"), "Cannot load XML!"); auto elDocument = need(doc.root().child("document"), "Need <document>"); for (pugi::xml_node elThing : elDocument.children("thing")) { auto attrName = need(elThing.attribute("name"), "Need <thing>.name!"); things.emplace_back( Thing { attrName.as_string(), elThing.text().as_string() } ); } for (auto &v : things) { std::cout << v.name << "=" << v.value << std::endl; } return 0; }
Бывают и гибридные API: внешние и маловажные части читаются потоковым методом, а внутренние и важные — объектным.
xml::StreamReader reader("in.xml"); std::string name, value; reader.enterTag("document"); while (reader.getTag("thing") { xml::Element* elThing = reader.readEntireSubtree(); things.emplace_back(); Thing& thing = things.back(); thing.name = elThing.requireStringAttr("name"); thing.value = elThing.text(); }
Запись XML: два варианта API
[править | править код]API прямой записи записывает XML тег за тегом, атрибут за атрибутом.
- + Быстр, нет промежуточных объектов.
- − Примитивная библиотека может делать неоптимальный XML (например,
<tag></tag>
вместо<tag />
). Работающая оптимально сложнее в программировании. - − Непригоден для отдельных специфических задач.
- − Если структуры предметной области работают ненадёжно, без специальных мер (записать в память или в другой файл, потом переименовать) можно остаться с «упавшей» программой и потерянным файлом.
- − При ошибке программиста может получиться синтаксически некорректный XML.
- − API только для записи, для чтения потребуется другой API.
- Примеры библиотек: StAX.
xml::Writer wri("out.xml"); wri.openTag("document"); for (auto &v : things) { wri.openTag("thing"); wri.writeAttr("name", v.name); wri.writeText(v.value); wri.closeTag("thing"); } wri.closeTag("document");
Объектный API, он же Document Object Model.
- − Создаёт объектную структуру для XML, что может отнять памяти больше, чем структура предметной отрасли.
- ± Универсален (впрочем, в большинстве задач преимущества над хорошо проработанным API прямой записи нет — в отличие от чтения).
- + Даже если структуры предметной области работают ненадёжно, а программист не предусмотрел никакой «защиты», единственный сценарий, когда файл перезаписывается на неполный — ошибка ввода-вывода (в частности, нехватка места на диске).
- + При правильно написанном API невозможно создать синтаксически некорректный XML.
- + Общий API для записи и чтения.
- Примеры библиотек: те же, что и для чтения XML методом DOM.
#include "pugixml.hpp" struct Thing { std::string name, value; }; Thing things[] { { "A", "Alpha", }, { "B", "Bravo", }, { "C", "Charlie" } }; int main() { pugi::xml_document doc; auto root = doc.append_child("document"); for (auto& thing : things) { auto node = root.append_child("thing"); node.append_attribute("name") = thing.name.c_str(); node.append_child(pugi::node_pcdata).set_value(thing.value.c_str()); } doc.save_file("test.xml"); return 0; }
Инструменты работы с документами: парсеры, средства создания и визуализации, системы баз данных
[править | править код]Реализации парсеров
[править | править код]XML имеет реализации парсеров для всех современных языков программирования[17].
Веб-браузеры как инструмент визуализации документа
[править | править код]Визуализация без использования стилей CSS
[править | править код]Без использования CSS или XSL XML-документ отображается как простой текст в большинстве веб-браузеров. Некоторые браузеры, такие как Internet Explorer, Mozilla Firefox и Opera (встроенный инструмент Opera Dragonfly) отображают структуру документа в виде дерева, позволяя сворачивать и разворачивать узлы с помощью нажатий клавиши мыши.
Применение стилей CSS
[править | править код]Процесс аналогичен применению CSS к HTML-документу для отображения. Для применения CSS при отображении в браузере, XML-документ должен содержать специальную ссылку на таблицу стилей. Например:
<?xml-stylesheet type="text/css" href="myStyleSheet.css"?>
Это отличается от подхода HTML, где используется элемент <link>.
Применение преобразований к формату XSL-FO
[править | править код]Современные браузеры принадлежат к числу программных средств, способных выполнять преобразования XSLT. В браузере такое преобразование выполняется, как правило, для форматирования документа (преобразования документа в формат XSL-FO). Следующая инструкция в прологе документа XML предписывает браузеру выполнить XSLT-преобразование, описанное в файле transform.xsl:
<?xml-stylesheet type="text/xsl" href="transform.xsl"?>
Редакторы XML
[править | править код]С документом XML можно работать в обычном текстовом редакторе, однако обычные редакторы не поддерживают структуру документа. Существуют специальные редакторы XML, которые делают работу с документом более удобной и эффективной.
Системы управления базами данных, работающие с данными в формате XML
[править | править код]Система управления базами данных DB2 позволяет хранить данные в формате XML и предоставляет доступ к таким данным с помощью языка XQuery.
Поддержка на аппаратном уровне
[править | править код]XML поддерживается на низком аппаратном, микропрограммном и программном уровнях в современных аппаратных решениях[18].
Область применения, ограничения, перспективы развития
[править | править код]Эффективность использования XML
[править | править код]XML — язык разметки, другими словами, средство описания документа. Именно в нише документов, текстов, где доля разнотипных символьных данных велика, а доля разметки мала — XML успешен. С другой стороны, обмен данными в открытых системах не сводится к обмену документами. Избыточность разметки XML (а в целях разработки языка прямо указано, что лаконичность не является приоритетом проекта) сказывается в ситуациях, когда данные не вписываются в традиционную модель документа. Лента новостей, например, оформляемая с использованием синтаксиса XML (форматы RSS, Atom), представляет собой не документ в традиционном понимании, а поток однотипных мини-документов — многословная и избыточная разметка в этом случае составляет существенную часть передаваемых данных.
W3C озабочен эффективностью применения XML, и соответствующие рабочие группы занимаются этой проблемой (к началу 2013 года нормативные документы не разработаны).
Другая ситуация, когда форматы XML могут оказаться не лучшим решением — работа с данными с простой структурой и небольшим объёмом символьных данных (поля данных). В этом случае доля разметки в общем объёме велика, а программная обработка XML может оказаться неоправданно затратной по сравнению с работой с данными более простой структуры. В этой области разработчики рассматривают средства, изначально ориентированные на данные, такие как INI, YAML, JSON.
Скриптовый язык для работы с XML
[править | править код]W3C работает над созданием скриптового языка для работы с XML (к началу 2013 года нормативные документы не разработаны).
См. также
[править | править код]- XML-RPC
- XML Schema
- SOAP (англ. Simple Object Access Protocol) — протокол передачи данных, в котором для сообщений используется формат XML.
- REST
- XHTML — версия HTML, отвечающая синтаксическим требованиям XML.
- XSD — язык описания структуры XML-документов.
- FB2 — формат описания книг, основанный на XML
- W3C DOM
- DITA
- WDDX
- APML
Примечания
[править | править код]- ↑ XML Media Types, RFC 3023 9–11. IETF (январь 2001). Дата обращения: 4 января 2010. Архивировано 22 августа 2011 года.
- ↑ XML Media Types, RFC 3023 7–9. IETF (январь 2001). Дата обращения: 4 января 2010. Архивировано 22 августа 2011 года.
- ↑ M. Murata, D. Kohn, and C. Lilley. Internet Drafts: XML Media Types . IETF (24 сентября 2009). Дата обращения: 10 июня 2010. Архивировано 22 августа 2011 года.
- ↑ Extensible Markup Language (XML) 1.0 (Fifth Edition) . Дата обращения: 6 июля 2011. Архивировано 1 апреля 2009 года.
- ↑ Extensible Markup Language (XML) 1.1 (Second Edition) . Дата обращения: 6 июля 2011. Архивировано 3 июля 2011 года.
- ↑ 1 2 Объяснение слова «entity» во спецификации языка XML. Дата обращения: 12 апреля 2014. Архивировано 10 января 2020 года.
- ↑ HTML Document Representation . www.w3.org. Дата обращения: 27 ноября 2019. Архивировано 23 декабря 2019 года.
- ↑ Объяснение слова «valid» в спецификации. Дата обращения: 12 апреля 2014. Архивировано 10 января 2020 года.
- ↑ Использование формы Бэкуса — Наура во спецификации. Дата обращения: 12 апреля 2014. Архивировано 10 января 2020 года.
- ↑ Запись пустого пространства в форме Бэкуса — Наура. Дата обращения: 12 апреля 2014. Архивировано 10 января 2020 года.
- ↑ If both the external and internal subsets are used, the internal subset MUST be considered to occur before the external subset.
- ↑ 1 2 3 4 5 6 7 8 Xml parsing . Дата обращения: 30 августа 2019. Архивировано 16 марта 2022 года.
- ↑ Streaming versus DOM (The Java EE 5 Tutorial) . Дата обращения: 9 апреля 2022. Архивировано 9 апреля 2022 года.
- ↑ 1 2 3 4 5 Comparing StAX to Other JAXP APIs (The Java EE 5 Tutorial) . Дата обращения: 9 апреля 2022. Архивировано 9 апреля 2022 года.
- ↑ 1 2 Pull Parsing versus Push Parsing (The Java EE 5 Tutorial) . Дата обращения: 9 апреля 2022. Архивировано 9 апреля 2022 года.
- ↑ StAX API (The Java™ Tutorials > Java API for XML Processing (JAXP) > Streaming API for XML) . Дата обращения: 9 апреля 2022. Архивировано 9 апреля 2022 года.
- ↑ XML Parsers . Дата обращения: 11 марта 2009. Архивировано из оригинала 3 марта 2009 года.
- ↑ Intel XML Accelerator (недоступная ссылка)
Литература
[править | править код]- Дэвид Хантер, Джефф Рафтер, Джо Фаусетт, Эрик ван дер Влист, и др. XML. Работа с XML, 4-е издание = Beginning XML, 4th Edition. — М.: «Диалектика», 2009. — 1344 с. — ISBN 978-5-8459-1533-7.
- Дэвид Хантер, Джефф Рафтер и др. XML. Базовый курс = Beginning XML. — М.: Вильямс, 2009. — 1344 с. — ISBN 978-5-8459-1533-7.
- Роберт Тейбор. Реализация XML Web-служб на платформе Microsoft .NET = Microsoft .NET XML Web Services. — М.: Вильямс, 2002. — 464 с. — ISBN 0-672-32088-6.
Ссылки
[править | править код]- XML на сайте Консорциума Всемирной паутины (W3C)
- Официальная спецификация стандарта XML 1.0 (англ.)
- Официальная спецификация стандарта XML 1.1 (англ.)
- Doug Tidwell. Введение в XML (недоступная ссылка)
- Документация по XML на сайте IBM статьи, форумы
- Просмотр XML Просмотр и редактирование данных XML (англ.)
- Форматирование XML Машина для онлайн-форматирования XML (англ.)
Для улучшения этой статьи желательно:
|