1. XML — это способ записи структурированных данных Под "структурированными данными" обычно подразумевают такие вещи, как электронные таблицы, адресные книги, файлы конфигурационных параметров и так далее. XML представляет собой набор правил (вы можете также считать их инструкциями или соглашениями) для разработки текстовых форматов, которые позволят вам структурировать ваши данные. XML обеспечивает однозначность структуры разрабатываемых документов. XML позволяет избежать распространенных ошибок проектирования «своих» языков: он расширяем, независим от платформы, включает поддержку интернационализации и локализации. XML полностью совместим с Unicode. Его использование не требует лицензии. 2. XML немного похож на HTML Также как и в HTML, в XML используются тэги (слова, заключенные в '<' и '>') и атрибуты (вида имя="значение"). Но если в HTML фиксируется смысловое значение каждого тэга и атрибута и то, как текст между ними будет выглядеть в браузере, в XML тэги используются только для логической разметки данных, и их интерпретация оставляется на усмотрение обрабатывающей программы. Другими словами, если вы встречаете "<p>" в XML-файле, то не стоит думать, что это параграф. В зависимости от контекста, это может быть цена (price), параметр (parameter), человек (person)... (вообще, кто сказал, что это должно быть слово, начинающееся с "p"?) 3. XML — это семейство технологий Существует спецификация XML 1.0, в которой определяется, что такое "тэги" и "атрибуты". Но за XML 1.0 следует "семейство XML" — все более растущее множество xml-подобных языков, предоставляющих полезные сервисы для решения важных и часто возникающих задач. Cпециальный язык стилей XSL и XSLT – языки трансформации, использующиеся для переформирования, трансформации исходного документа XML. Языки XML Schema 1 и 2 призваны помочь разработчикам четко определять их собственные форматы, основанные на XML. Кроме перечисленных готово к использованию или находится в разработке еще множество языков на базе XML. XML — не всегда лучшее решение, но всегда стоит принимать его во внимание. 4. Как выглядит XML-документ? Если Вы знакомы с HTML, изучение XML не потребует от Вас особых усилий. Хотя XML, безусловно, сильно отличается по своим возможностям и предназначению от языка гипертекстовой разметки, оба эти языка являются подмножествами SGML, и, следовательно, наследуют его базовые принципы. Структура документа Простейший XML- документ может выглядеть так, как это показано в Примере 1 <?xml version="1.0"?> <list_of_items> <item id="1">Первый</item> <item id="2">Второй <sub_item>подпункт 1</sub_item></item> <item id="3">Третий</item> <item id="4">Последний</item> </list_of_items> Обратите внимание на то, что этот документ очень похож на обычную HTML-страницу. Также, как и в HTML, инструкции, заключенные в угловые скобки называются тэгами и служат для разметки основного текста документа. В XML существуют открывающие, закрывающие и пустые тэги (в HTML понятие пустого тэга тоже существует, но специального его обозначения не требуется). Тело документа XML состоит из элементов разметки (markup) и непосредственно содержимого документа - данных (content). XML - тэги предназначены для определения элементов документа, их атрибутов. Более подробно о типах применяемой в документах разметки, мы поговорим чуть позже. Любой XML- документ должен всегда начинаться с инструкции <?xml?>, внутри которой также можно задавать номер версии языка, номер кодовой страницы и другие параметры, необходимые программе-анализатору в процессе разбора документа. Ниже приведен пример начала документа xml. <?xml version="1.0" encoding="windows-1251"?> … Правила создания XML- документа В общем случае XML- документы должны удовлетворять следующим требованиям: В заголовке документа помещается объявление XML, в котором указывается язык разметки документа, номер его версии и дополнительная информация Каждый открывающий тэг, определяющий некоторую область данных в документе обязательно должен иметь своего закрывающего "напарника", т.е., в отличие от HTML, нельзя опускать закрывающие тэги В XML учитывается регистр символов Все значения атрибутов, используемых в определении тэгов, должны быть заключены в кавычки Вложенность тэгов в XML строго контролируется, поэтому необходимо следить за порядком следования открывающих и закрывающих тэгов Вся информация, располагающаяся между начальным и конечными тэгами, рассматривается в XML как данные и поэтому учитываются все символы форматирования ( т.е. пробелы, переводы строк, табуляции не игнорируются, как в HTML) xml – регистрочувствительный язык. Если XML- документ не нарушает приведенные правила, то он называется формальноправильным и все анализаторы, предназначенные для разбора XML- документов, смогут работать с ним корректно. Однако кроме проверки на формальное соответствие грамматике языка, в документе могут присутствовать средства контроля над содержанием документа, за соблюдением правил, определяющих необходимые соотношений между элементами. Например, следующий текст, являясь вполне правильным XML- документом, будет абсолютно бессмысленным: <country><title>Russia</title><city><title>Novosibirsk</title></city></country> Для того, чтобы обеспечить проверку корректности XML-документов, необходимо использовать анализаторы, производящие такую проверку и называемые верифицирующими. На сегодняшний день существует два способа контроля правильности XML- документа: DTD - определения(Document Type Definition) и схемы данных(Semantic Schema). Более подробно об использовании DTD и схемах мы поговорим в следующих разделах. Определение DTD-правил и схемы для XML-документа, в принципе, не обязательно. Конструкции языка Содержимое XML- документа представляет собой набор элементов, секций CDATA, директив анализатора, комментариев, спецсимволов, текстовых данных. Рассмотрим каждый из них подробней. Элементы данных Элемент - это структурная единица XML- документа. Заключая слово rose в тэги <flower> </flower> , мы определяем непустой элемент, называемый <flower>, содержимым которого является rose. В общем случае в качестве содержимого элементов могут выступать как просто какой-то текст, так и другие, вложенные, элементы документа, секции CDATA, комментарии, - т.е. практически любые части XML- документа. Любой непустой элемент должен состоять из начального, конечного тэгов и данных, между ними заключенных. Например, следующие фрагменты будут являться элементами: <flower>rose</flower> <city>Novosibirsk</city> <apple/> ,а эти – нет (т.к. они не закончены): <rose> <flower> rose Набором всех элементов, содержащихся в документе, задается его структура и определяются все иерархические соотношения. Плоская модель данных превращается с использованием элементов в сложную иерархическую систему со множеством возможных связей между элементами. Например, в следующем примере мы описываем месторасположение Новосибирских университетов (указываем, что Новосибирский Университет расположен в городе Новосибирске, который, в свою очередь, находится в России), используя для этого вложенность элементов XML : <country id="Russia"> <cities-list> <city> <title>Новосибирск</title> <state>Siberia</state> <universities-list> <university id="1"> <title>Новосибирский Государственный Технический Университет</title> <noprivate/> <address URL="www.nstu.ru"/> <description>очень хороший институт</description> </university> <university id="2"> <title>Новосибирский Государственный Университет</title> <noprivate/> <address URL="www.nsu.ru"/> <description>тоже не плохой</description> </university> </universities-list> </city> </cities-list> </country> Производя в последствии поиск в этом документе, программа будет опираться на информацию, заложенную в его структуру - используя элементы документа. Т.е. если, например, требуется найти нужный университет в нужном городе, используя приведенный фрагмент документа, то необходимо будет просмотреть содержимое конкретного элемента <university>, находящегося внутри конкретного элемента <city>. Поиск при этом, естественно, будет гораздо более эффективен, чем нахождение нужной последовательности по всему документу. В XML документе, как правило, определяется хотя бы один элемент, называемый корневым и с него программы-анализаторы начинают просмотр документа. В приведенном примере этим элементом является <country> В некоторых случаях тэги могут изменять и уточнять семантику тех или иных фрагментов документа, по разному определяя одну и ту же информацию и тем самым предоставляя приложению-анализатору этого документа сведения о контексте использования описываемых данных. Например, прочитав фрагмент <city>Holliwood</city> мы можем догадаться, что речь в этой части документа идет о городе, а вот во фрагменте <restaurant>Holliwood</restaurant> - о кафе. В случае, если элемент не имеет содержимого, т.е. нет данных, которые он должен определять, он называется пустым. Примером пустых элементов в HTML могут служить такие тэги HTML, как <br>, <hr>, <img>;. Необходимо только помнить, что начальный и конечные тэги пустого элемента как бы объединяются в один, и надо обязательно ставить косую черту перед закрывающей угловой скобкой (например, <empty/>;) Комментарии Комментариями является любая область данных, заключенная между последовательностями символов <!-- и --> Комментарии пропускаются анализатором и поэтому при разборе структуры документа в качестве значащей информации не рассматриваются. Атрибуты Если при определении элементов необходимо задать какие-либо параметры, уточняющие его характеристики, то имеется возможность использовать атрибуты эдлемента. Атрибут - это пара "название" = "значение", которую надо задавать при определении элемента в начальном тэге. Пример: <color RGB="true">#ff08ff</color> <color RGB="false">white</color> или <author id=0>Ivan Petrov</author> Примером использования атрибутов в HTML является описание элемента <font>: <font color="white" name="Arial">Black</font> Cпециальные символы Для того, чтобы включить в документ символ, используемый для определения каких-либо конструкций языка (например, символ угловой скобки) и не вызвать при этом ошибок в процессе разбора такого документа, нужно использовать его специальный символьный либо числовой идентификатор. Например, &lt; , &gt; &quot; или &#036;(десятичная форма записи), &#x1A (шестнадцатеричная) и т.д. Строковые обозначения спецсиволов могут определяться в XML документе при помощи компонентов (entity), о чем мы еще поговорим немного позже. Директивы анализатора Инструкции, предназначенные для анализаторов языка, описываются в XML документе при помощи специальных тэгов - <? и ?>;. Программа клиента использует эти инструкции для управления процессом разбора документа. Наиболее часто инструкции используются при определении типа документа (например, <? xml version="1.0"?>) или создании пространства имен. CDATA Чтобы задать область документа, которую при разборе анализатор будет рассматривать как простой текст, игнорируя любые инструкции и специальные символы, но, в отличии от комментариев, иметь возможность использовать их в приложении, необходимо использовать тэги <![CDATA] и ]]>. Внутри этого блока можно помещать любую информацию, которая может понадобится программе для выполнения каких-либо действий (в область CDATA, можно помещать, например, инструкции JavaScript, предварительно преобразовав все символы операций «больше-меньше» в спецсимволы). Естественно, надо следить за тем, чтобы в области, ограниченной этими тэгами не было последовательности символов ]]. 5. Что такое Namespaces? Как уже упоминалось ранее, вся прелесть использования XML заключается в возможности придумывания собственных тэгов, названия которых наиболее полно соответствовали бы предназначению. Но фантазия и словарный запас людей не безграничны, поэтому нет абсолютно никакой гарантии того, что данные вами имена элементов не будут использованы кем-то еще. Вполне возможна ситуация, когда один и тот же документ будет содержать информацию для нескольких обработчиков одновременно, записанную разными подмножествами разработанных кем-то наборов тэгов. В этом случае названия некоторых элементов или их атрибутов могут совпасть, что вызовет либо ошибку в XML- анализаторе, либо неправильную интерпретацию документа. Чтобы исправить эту ситуацию, мы должны определить уникальные названия элементов и их атрибутов, "дописывая" к их обычным именам некоторый универсальный неповторяющийся префикс. Для этого применяется механизм Namespaces (спецификация Namespaces была официально утверждена W3C в январе 1999 года и сегодня является частью стандарта XML). Согласно этой спецификации, для определения "области действия" тэга необходимо определить уникальный атрибут, описывающий название элемента, по которому анализатор документа сможет определить, к какой группе имен оно относится (Namespace идентификаторы могут применяться для описания уникальных названий как элементов, так и их атрибутов). Пример неоднозначного файла (тэг language описывает язык программирования, который изучал студент и его родной разговорный язык; тэг rating – оценку по предмету и средний балл при поступлении): <student> <id>3235329</id> <name>Jill Smith</name> <language>Spanish</language> <rating>3.2</rating> </student> <student> <id>3235329</id> <language>C#</language> <rating>9.5</rating> </student> Namespace определяется посредством атрибута xmlns и уникального URI, например, ниже описан фрагмент документа xml с одноименными тэгами различных смысловых групп. <base:student xmlns:base = “http://www.ed.gov/elementary/students”> <base:id>3235329</base:id> <base:name>Jill Smith</base:name> <base:language>Spanish</base:language> <base:rating>3.2</base:rating> </base:student> <prog:student xmlns:prog = http://www.develop.com/student xmlns:base = “http://www.ed.gov/elementary/students”> <base:id>3235329</base:id> <prog:language>C#</prog:language> <prog:rating>9.5</prog:rating> </prog:student> Уникальность атрибуту имени обеспечивает использование в качестве его значения некоторых универсальных идентификаторов ресурсов (URI, например, http://www.ed.gov/elementary/students) 6. Схемы документа XML Если XML документ создан и мы убедились, что набор используемых при этом тэгов позволяет осуществлять любые манипуляции с нашей информацией, то, чтобы утвердить правила нашего нового языка, т.е. список допустимых элементов, их возможное содержимое и атрибуты, мы можем создать описание его грамматики (иными словами - шаблон или схему документа). Такой подход имеет целый ряд ценных преимуществ: Невозможно использовать документ, не удовлетворяющий схеме Значительно упрощается анализ документа Составитель документов такого типа получает исчерпывающее формальное описание допустимой структуры. 6.1 DTD (Document Type Definition) схема документа В DTD для XML используются следующие типы правил: правила для элементов и их атрибутов, описания категорий (аналог макроопределений в языках программиования), описание форматов бинарных данных. Для того, чтобы использовать DTD в нашем документе, мы можем или описать его во внешнем файле и при описании DTD просто указать ссылку на этот файл или же непосредственно внутри самого документа выделить область, в которой определить нужные правила. В первом случае в документе указывается имя файла, содержащего DTD- описания: <?xml version="1.0" standalone="no" ?> <!DOCTYPE journal SYSTEM "journal.dtd"> ... где journal – имя корневого тега XML – документа Внутри же документа DTD- декларации включаются следующим образом: <?xml version="1.0" standalone="yes" ?> <!DOCTYPE journal [ <!ELEMENT journal (contacts, issues, authors)> ... ]> ... В том случае, если используются одновременно внутренние и внешние описания, то программой-анализатором будут сначала рассматриваться внутренние, т.е. их приоритет выше. При проверке документа XML- процессор в первую очередь ищет DTD внутри документа. Если правила внутри документа не определены и не задан атрибут standalone ="yes" , то программа загрузит указанный внешний файл и правила, находящиеся в нем, будут считаны оттуда. Если же атрибут standalone имеет значение "yes", то использование внешних DTD описаний будет запрещено. Определение тэга Тэг в DTD определяется с помощью дескриптора !ELEMENT, в котором указывается название элемента и структура его содержимого. Например, для элемента <flower> можно определить следующее правило: <!ELEMENT flower (#PCDATA) > Ключевое слово ELEMENT указывает, что данной инструкцией будет описываться элемент XML. Внутри этой инструкции задается название элемента(flower) и тип его содержимого. В определении элемента мы указываем сначала название элемента(flower), а затем его модель содержимого - определяем, какие другие элементы или типы данных могут встречаться внутри него. В данном случае содержимое элемента flower будет определяться при помощи специального маркера PCDATA( что означает parseable character data - любая информация, с которой может работать программа-анализатор). Существует еще две инструкции, определяющие тип содержимого: EMPTY и ANY. Первая указывает на то, что элемент должен быть пустым(например, <red/>), вторая - на то, что содержимое элемента специально не описывается и может быть любым. Последовательность дочерних для текущего элемента объектов задается в виде списка разделенных запятыми названий элементов. При этом для того, чтобы указать количество повторений включений этих элементов могут использоваться символы +,*, ? : <!ELEMENT issue (title, author+, table-of-contents?)> В этом примере указывается, что внутри элемента <issue> должны быть определены элементы title, author и table-of-contents, причем элемент title является обязательным элементом и может встречаться лишь однажды, элемент author может встречаться несколько раз, а элемент table-of-contents является опциональным, т.е. может отсутствовать. В том случае, если существует несколько возможных вариантов содержимого определяемого элемента, их следует разделять при помощи символа "|" : <!ELEMENT flower (family | title )*> Символ * в этом примере указывает на то, что определяемая последовательность внутренних элементов может быть повторена несколько раз или же совсем не использоваться. Если в определении элемента указывается "смешанное" содержимое, т.е. текстовые данные или набор элементов, то необходимо сначала указать PCDATA, а затем разделенный символом "|" список элементов. Пример корректного XML- документа: <?xml version="1.0"?> <!DOCTYPE journal [ <!ELEMENT contacts (address, tel+, email?)> <!ELEMENT address (street, appt)> <!ELEMENT street (#PCDATA)> <!ELEMENT appt (#PCDATA | EMPTY)*> <!ELEMENT tel (#PCDATA)> <!ELEMENT email (#PCDATA)> ]> ... <contacts> <address> <street>Marks avenue</street> <appt id="4"> </address> <tel>12-12-12</tel> <tel>46-23-62</tel> <email>info@j.com</email> </contacts> Определение атрибутов тэгов Списки атрибутов элемента определяются с помощью ключевого слова !ATTLIST. Внутри него задаются названия атрибутов, типы их значений и дополнительные параметры. Например, для элемента <article> могут быть определены следующие атрибуты: <!ATTLIST article id ID #REQUIRED about CDATA #IMPLIED type (actual | review | teach ) 'actual' > В данном примере для элемента article определяются три атрибута: id, about и type, которые имеют типы ID(идентификатор), CDATA и список возможных значений соответственно. Всего существует шесть возможных типов значений атрибута: CDATA - содержимым документа могут быть любые символьные данные ID - определяет уникальный идентификатор элемента в документе IDREF( IDREFS )- указывает, что значением атрибута должно выступать название(или несколько таких названий, разделенных пробелами во втором случае) уникального идентификатора определенного в этом документе элемента ENTITY( ENTITIES) - значение атрибута должно быть названием(или списком названий, если используется ENTITIES) компонента (макроопределения), определенного в документе NMTOKEN (NMTOKENS) - содержимым элемента может быть только одно отдельное слово(т.е. этот параметр является ограниченным вариантом CDATA) Список допустимых значений - определяется список значений, которые может иметь данный атрибут. Также в определении атрибута можно использовать следующие параметры: #REQUIRED - определяет обязательный атрибут, который должен быть задан во всех элементах данного типа #IMPLIED - атрибут не является обязательным #FIXED "значение" - указывает, что атрибут должен иметь только указанное значение, однако само определение атрибута не является обязательным, но в процессе разбора его значение в любом случае будет передано программе-анализатору значение - задает фиксированное значение атрибута. Определение компонентов (макроопределений) Компонент (entity) представляет собой определения, содержимое которых может быть повторно использовано в документе. В других языках программирования подобные элементы называются макроопределениями. Создаются DTD- компоненты при помощи инструкции !ENTITY: <!ENTITY hello 'Мы рады приветствовать Вас!' > Программа-анализатор, просматривая в первую очередь содержимое области DTDопределений, обработает эту инструкцию и при дальнейшем разборе документа будет использовать содержимое DTD- компонента в том месте, где будет встречаться его название. Т.е. теперь в документе мы можем использовать выражение &hello; , которое будет заменено на строчку "Мы рады приветствовать Вас" (Обратите внимание на &, это не опечатка, а признак подстановки) В общем случае, внутри DTD можно задать три типа макроопределений: Внутренние макроопределения - предназначены для определения строковой константы, с их помощью можно организовывать ссылки на часто изменяемую информацию, делая документ более читабельным. Внутренние компоненты включаются в документ при помощи амперсанда & В XML существует пять предустановленных внутренних символьных констант: &lt; - символ "<" &gt; - символ ">" &amp; - символ "&" &apos; - символ апострофа "’" &quot; - символ двойной кавычки """ Макроопределения правил - макроопределения правил могут использоваться только внутри области DTD и обозначаются специальным символом %, вставляемым перед названием макроса. При этом содержимое компонента будет помещено непосредственно в текст DTD- правила Например, для следующего фрагмента документа: <!ELEMENT name (#PCDATA)> <!ELEMENT title (#PCDATA | name)*> <!ELEMENT author (#PCDATA | name)*> <!ELEMENT article (title, author)*> <!ELEMENT book (title, author)*> <!ELEMENT bookstore (book | article)*> <!ELEMENT bookshelf (book | article)*> можно использовать более короткую форму записи: <!ELEMENT name (#PCDATA)> <!ENTITY % names '#PCDATA | name'> <!ELEMENT article (%names;)*> <!ELEMENT book (%names;)*> <!ENTITY % content 'book | article'> <!ELEMENT bookstore (%content;)*> <!ELEMENT bookshelf (%content;)*> Макроопределения часто используются для описания параметров в правилах атрибутов. В этом случае появляется возможность использовать одинаковые определения атрибутов для различных элементов: <!ENTITY % itemattr 'id ID #IMPLIED'> <!ENTITY % bookattr 'ISDN ID #IMPLIED'> <!ENTITY % artattr " size CDATA'> <!ELEMENT book (title, author,content)*> <!ATTLIST book %itemattr; %bookattr;> <!ELEMENT article (title, author, content)*> <!ATTLIST article %itemattr; %artattr;> Ниже приведен пример, реализующий разметку документа, содержащего описание дерева файлов и каталогов: <?xml version=«1.0» encoding=«Windows-1251»?> <!DOCTYPE filetree [ <!ELEMENT filetree (device)+> <!ELEMENT device (name,directory*)> <!ELEMENT name (#PCDATA)> <!ELEMENT directory (dirinfo?,directory*,file*)> <!ELEMENT dirinfo (#PCDATA)> <!ATTLIST directory name CDATA #REQUIRED> <!ELEMENT file (#PCDATA)> <!ATTLIST file modified CDATA #REQUIRED size CDATA #REQUIRED> > ]> <?xml version=«1.0» encoding=«windows-1251»?> <filetree> <device> <name>C:</name> <directory name=«/»> <dirinfo/> <directory name=«Anti»> <file modified=”1994-11-05” size=”500” >drweb.exe</file> <file modified=”1997-04-12” size=”7000”>aidstest.exe</file> <file modified=”2004-09-24” size=”10”>norton.exe</file> </directory> <directory name=«Arch»> <directory name=«Rar»> <file modified=”2003-07-05” size=”2300”>rar.exe</file> </directory> <file modified=”1996-10-03” size=”5200”>arj.exe</file> <file modified=”2001-12-07” size=”4000”>pkzip.exe</file> </directory> <directory name=«Tmp»/> </directory> </device> <device> <name>D:</name> <directory name=«/»/> </device> </filetree> Несмотря на кажущуюся простоту, DTD-представление обладает некоторыми неочевидными особенностями. Прежде всего, схема DTD не является XML-подмножеством, что, безусловно, создает некоторые неудобства в ее использовании внутри XML. Кроме этого, описательные способности такой схемы сильно ограничены и фактически позволяют контролировать только вложенность тэгов, но не их содержание. Поэтому, разрабатываются также более мощные средства описания структуры документа. 6.2 Схемы XDR Перечисленных недостатков DTD лишены схемы XDR (XML Data Reduced Schema), использование которых становится доступным после установки пакета XML SDK. Ключевыми особенностями таких схем, прежде, всего являются: Тонкое определение множества простых типов данных Возможность определения составных типов данных Организация схемы на XML-подобном языке Зарезервированных тегов у XDR-схемы немного: <attribute>, <AttributeType>, <datatype>, <description>, <element>, <ElementType>, <group>, <Schema>. В соответствии с концепцией XML регистр букв в данном случае имеет значение и, к примеру, тэг <schema> зарезервированным являться не будет. Перед тем, как перейти к детальному рассмотрению XDR-схем, полезно иметь в виду таблицу возможных атрибутов: Тэг <attribute> <AttributeType> <datatype> <description> <element> <ElementType> <group> <Scema> Атрибуты type="тип"; default="значение по умолчанию"; required="yes|no" name="имя атрибута" default="значение по умолчанию" dt:maxLength="" dt:minLength="" dt:type="bin.base64 | bin.hex | boolean | char | date | dateTime | dateTime.tz | entities | entity | enumeration | fixed.14.4 | float | i1| i2 | i4 | i8 | id | idref | idrefs | int | nmtoken | nmtokens | notation | number | r4 | r8 | string | time | time.tz | ui1 | ui2 | ui8 | ui8 | uri | uuid" dt:values="список значений" required="yes|no" xmlns:dt='urn:schemas-microsoft-com:datatypes" dt:type="тип данных" xmlns:dt="urn:schemas-microsoft-com:datatypes" Отсутствуют type="тип" maxOccurs="максимальное количество" minOccurs="минимальное количество" name="имя элемента" content="eltOnly | empty | mixed | textOnly" dt:maxLength="" dt:minLength="" dt:type="тип данных" dt:values="" model="closed|open" order="many | one | seq" required="yes|no" xmlns:dt="urn:schemas-microsoft-com:datatypes" maxOccurs="максимальное количество" minOccurs="минимальное количество" order="many | one | seq" name="имя схемы" xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemasmicrosoft-com:datatypes" xmlns=«urn:schemas-microsoft-com:xml-data» и xmlns:dt=«urn:schemas-microsoft-com:datatypes» - зарезервированные пространства имен SDR Для подключения к файл.xml схемы необходимо добавить следующий атрибут: xmlns=«x-schema:имя_файла.xdr» в его корневой тег Для приведенного выше примера структуры каталогов на диске XDR-схема взамен DTD прведена в примере на диске (методические указания \xml\ex_xdr): Из примера видно, что схема описывается как совокупность вложенных элементов определенного типа: простого (например, int) или пользовательского составного (filetree). Каждый <ElementType> содержит внутри теги, определяющие названия и описания собственных атрибутов, а также названия и количество вложенных тегов, описания которых вынесены в отдельные блоки <ElementType>. Получается, что вложенная структура преобразуется в описательную цепочку, связи между звеньями которой осуществляются с помощью тега <element>. Как видно из примера, внутри тэга <element> находятся два атрибута (minOccurs и maxOccurs), с помощью которых мы полностью контролируем количество тэгов в XML-документе. Так, значение maxOccurs="*" говорит нам о том, что максимальное количество тэгов не ограничено. Другим важным фактором контроля является использование атрибута dt:type, позволяющего задавать тип ячейки информации. Множество всех доступных значений типа приведено выше в таблице. Совокупность атрибутов name и type представляет собой связь между звеньями <ElementType> и в дополнительных комментариях, я думаю, не нуждается. Смысл атрибута required тоже очевиден. В итоге остаются атрибуты model, content и order, которые, несомненно, заслуживают более пристального внимания. Атрибут model может принимать одно из двух значений: open и close. В случае open элемент может содержать другие элементы, не описанные в схеме. Для close соответствие документа и схемы должно быть однозначным. Значениями атрибута content могут быть: empty, textOnly, eltOnly и mixed, обозначающие пустое, текстовое, элементное или смешанное наполнение. И, наконец, атрибут order позволяет выбрать значение из альтернатив: one, seq, many. Значение one говорит строгой определенности и единичности вложенного элемента, seq позволяет описать определенную последовательность тэгов, а many соответствует комбинации "ноль или более" и по смыслу перекрывает атрибуты minOccurs и maxOccurs. 6.3 Кое-что об XSD (XML Schema Definition) XSD включает в себя большинство возможностей XDR-схемы и дополняет их весьма солидным набором собственных тегов. В XSD-описании зарезервировано порядка пятидесяти специальных тэгов. Говоря о возможностях описания в стиле XSD необходимо сразу упомянуть следующие моменты: Схема XSD позволяет описывать ограничения (<xsd:restriction>), Выполнять подключение внешних файлов (<xsd:include schemaLocation=«»>), Реализовывать не только группы (<xsd:group>), но и последовательности (<xsd:sequence>), альтернативы(<xsd:choice>), Организовывать сложные типы данных, такие как списки (<xsd:list>), перечисления (<xsd:enumeration>), объединения (<xsd:union>) и уникальные ключи (<xsd:unique>), Осуществлять проверки с помощью регулярных выражений (!), Использовать язык запросов к документы XPath, Реализовывать тэговые ссылки с помощью атрибута ref Полный перечень этим не заканчивается, но возможности, очевидно, грандиозны и, может быть, даже избыточны для простых XML документов. Используя XSD попробуем еще раз описать дерево каталогов (см. пример на диске ex_xsd): Приведем его фрагмент для описания содержимого тэга «имя файла», которое содержит имя и расширение суммарной длиной не более 255 символов, содержащего латинские буквы, цифры и символ подчеркивания. <xsd:simpleType name="fileName"> <xsd:restriction base="xsd:string"> <xsd:minLength value="1"/> <xsd:maxLength value="255"/> <xsd:whiteSpace value="collapse"/> <xsd:pattern value="[a-zA-Z0-9_]{1,250}\.[a-zA-z]{1,5}"/> </xsd:restriction> </xsd:simpleType> Для подключения схемы к документу необходимо изменить корневой тег на следующий: <корневой тэг xmlns="http://filesystem.xsd/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://filesystem.xsd/schema имя_файла_со_схемой.xsd"> Пример xsd схемы можно посмотреть по адресу «Методические указания\xml\ex_xsd». Подробное описание принципов разарботки xsd схем можно найти по адресу «Методические указания\xml\schema.pdf». Контроль документа на соответствие схеме Итак, мы рассмотрели популярные и широко используемые диалекты описания схем XML. Для того, чтобы обсуждать программный контроль структуры xml документа необходимо ознакомиться с программными интерфейсами доступа к его элементам. 7. DOM Одним из самых мощных интерфейсов доступа к содержимому XML документов является Document Object Model - DOM. Объектная модель XML документов является представлением его внутренней структуры в виде совокупности определенных объектов. Для удобства эти объекты организуются в некоторую древообразную структуру данных - каждый элемент документа может быть отнесен к отдельной ветви, а все его содержимое, в виде набора вложенных элементов, комментариев, секций CDATA и т.д. представляется в этой структуре поддеревьями. Т.к. в любом правильно составленном XML-документе обязательно определен главный элемент, то все содержимое можно рассматривать как поддеревья этого основного элемента, называемого в таком случае корнем дерева документа. DOM - это спецификация (интерфейс) универсального платформо- и программнонезависимого доступа к содержимому документов и является просто своеобразным API для их обработчиков. DOM является стандартным способом построения объектной модели любого HTML или XML документа, при помощи которой можно производить поиск нужных фрагментов, создавать, удалять и модифицировать его элементы. Internet Explorer DOM Для сценариев, исполняемых в браузере, доступно множество объектов для работы с XMLдокументом. Полное их описание можно посмотреть в документации MSDN, здесь же рассмотрим лишь самые важные из них, объекты XMLDOMDocument, XMLDOMNode, XMLDOMNodeList, представляющие интерфейс для доступа ко всему документу, отдельным его узлам и поддеревьям соответственно. Также рассмотрим объект XMLDOMParseError, предоставляющий необходимую для отладки информацию о произошедших ошибках анализатора. Объект DOMDocument Представляет верхний уровень объектной иерархии и содержит методы для работы с документом: его загрузки, анализа, создания в нем элементов, атрибутов, комментариев и т.д. Многие свойства и методы этого объекта реализованы также в рассмотренном ниже классе Node, т.к. документ может быть рассмотрен как корневой узел с вложенными в него поддеревьями. Свойства Получение и информации о текущем состоянии процесса загрузки и анализа документа. Async Свойство, доступное для записи и чтения, идентифицирующее текущий режим обработки (синхронный или асинхронный) parseError Возвращает ссылку на объект XMLDOMParseError, при помощи которого можно получить всю необходимую информацию о последней ошибке анализатора. Только для чтения. readyState Содержит информацию о текущем состоянии анализатора: LOADING (1) - находится в процессе загрузки документа LOADED (2) - загрузка завершена, но объектная модель документа еще не создана INTERACTIVE (3) - объектная модель создана(все элементы документа разобраны, установлены их связи и атрибуты) но доступна пока только для чтения COMPLETED (4) - с ошибками или без, но документ разобран Для получения своевременной информации о текущем состоянии анализатора можно воспользоваться обработчиком событий onreadystatechange Только для чтения. Событие ondataavailable Свойство, доступное только для записи, которое содержит ссылку на обработчик события ondataavailable (вызывается, когда обработчик обрабатывает очередную порцию данных документа) Событие onreadystatechange Ссылка на обработчик события onreadystatechange (вызывается каждый раз, когда меняется состояние обработчика - свойство readyState) Событие ontransformnode Ссылка на обработчик события ontransformnode (вызывается перед каждой трансформацией узла стилевыми таблицами) Изменение параметров обработчика. preserveWhiteSpace Определяет, должны ли при разборе документа игнорироваться символы разделителей. Если значение свойства ложно, то будут, если истина - то разделители будут сохранены. По умолчанию установлено в false. Доступно для чтения и записи. resolveExternals Свойство определяет, будут ли в процессе анализа разбираться внешние определения (DTD-описания, макроподстановки и т.д.) - значение true или нет(false). Доступно для чтения и записи. validateOnParse Включение - выключение верификации документа. Значения true или false. Доступно для чтения и записи. Получение информации о загруженном документе doctype Возвращает тип документа, определяемый при его создании тэгом <!DOCTYPE>, включающим DTD. Если в документе нет DTD описаний, возвращается null. Только для чтения. url Возвращает URL документа(в случае успешной его загрузки, в противном случае возвращает null). Доступно только для чтения. documentElement Содержит ссылку на корневой элемент документа в виде объекта XMLDOMElement. Если корневого элемента нет, то возвращается null. Доступно для записи schemas Содержит XML схему (XDR , XSD) присоединенную к документу. Она загружается отдельно от документа «вручную» или вместе с ним. (см. пример контроль качества в папках ex_xdr или ex_xsd) Методы Загрузка и сохранение документов load(url) Загружает документ, адрес которого задан параметром url. В случае успеха возвращает логическое значение true. Необходимо иметь в виду, что вызов этого метода сразу же обнуляет содержимое текущего документа loadXML(xmlString) Загружает XML - фрагмент, определенный в передаваемой строке save(objTarget) Сохраняет документ в файле (objTarget - строка, содержащая URL файла) или внутри другого документа (objTarget - объект XMLDOMDoument). abort() Прерывание процесса загрузки и обработки документа. Обработчик ошибок XMLDOMParseError будет содержать в коде ошибки соответствующее значение. Создание новых объектов. Необходимо отметить, что все методы лишь создают указанные объекты и для включения их в объектную модель документа надо дополнительно использовать методы insertBefore, insertAfter или appendChild. createAttribute (name) Создает новый атрибут с указанным именем. Новый атрибут добавляется в объектную модель документа только после применения метода узла setAttribute. createNode(Type, name, nameSpaceURI) Создает узел указанного типа и названия. Namespace префикс задается параметром nameSpaceURI. Возвращаемым значением будет созданный объект указанного типа. createCDATASection(data) Создает область CDATA - возвращает объект XMLDOMCDATASection createDocumentFragment() Создает новый пустой фрагмента документа - объект XMLDOMDocumentFragment createComment(data) Создает комментарий. createElement(tagName) Создает элемент документа с указанным названием. createEntityReference(name) Создает ссылку на подстановочные символы createProcessingInstruction(target, Создает новую директиву XML-процессора data) createTextNode(data) Поиск узлов дерева документа Создает текст внутри документа getElementsByTagName(tagname) Возвращает ссылку на коллекцию элементов документа с заданным именем (или всех элементов, если значение tagname равно "*") selectNodes(pattern) Возвращает набор узлов, удовлетворяющих шаблону поиска hasChildNodes() Возвращает истину, если текущий узел содержит поддерево. Объект XMLDOMNode Объект XMLDOMNode, реализующий базовый DOM интерфейс Node, предназначен для манипулирования с отдельным узлом дерева документа. Его свойства и методы позволяют получать и изменять полную информацию о текущем узле - его тип (является ли текущий узел элементом, комментарием, текстом и т.д.), название, полное название (вместе с Namespace префиксом), его содержимое, список дочерних элементов и т.д. Свойства Общая информация о текущем элементе дерева nodeName Возвращает полное название(вместе с Namaspace атрибутом) текущего узла в виде строки. Доступно только для чтения. baseName Возвращает название элемента без префикса Namespace. Только для чтения. Prefix Возвращает Namespace префикс. Только для чтения. namespaceURI Возвращает URI Namespace префикса текущего элемента dataType Определяет тип содержимого текущего узла(описываемое схемами данных). Доступно для записи и чтения nodeType Возвращает тип текущего узла: NODE_ELEMENT (1) - элемент NODE_ATTRIBUTE (2) - атрибут NODE_TEXT (3) - текст NODE_CDATA_SECTION (4) - область CDATA NODE_ENTITY_REFERENCE (5) - объект ссылки на "макроподстановки" NODE_ENTITY (6) - объект ссылки на т.н. "подстановочые символы" - entity" NODE_PROCESSING_INSTRUCTION (7) - область инструкций XML процессору NODE_COMMENT (8) - комментарий NODE_DOCUMENT (9) - корневой элемент документа NODE_DOCUMENT_TYPE (10) - описание типа документа, задаваемое тэгом <!DOCTYPE> NODE_DOCUMENT_FRAGMENT (11) - фрагмент XML-документа - несвязанное поддерево NODE_NOTATION (12) - DTD нотация. Свойство доступно только для чтения. nodeTypeString Возвращает тип узла в виде текста. Только для чтения. attributes Возвращает список атрибутов текущего узла в виде коллекции XMLDOMNamedNodeMap. Если атрибутов нет, то свойство length будет содержать нулевое значение. Для тех узлов, у которых не может быть атрибутов (в XML документе они могут быть назначены лишь объектам элементов, макроподстановок и нотаций) возвращается null. Для объектов макроподстановок и нотаций содержимым коллекции будут являться атрибуты SYSTEMID, PUBLICID и NDATA. Доступно только для чтения. definition Содержимое текущего узла Возвращает DTD определение для текущего узла дерева. Text Возвращает содержимое текущего поддерева(узла и всех его дочерних элементов). Доступно для записи и чтения Xml Возвращает XML-представление текущего поддерева. Доступно только для чтения nodeValue Возвращает содержимое текущего узла. Доступно для чтения и записи. Работа со списком дочерних элементов childNodes Для тех узлов, которые имеют дочерние элементы возвращает их список в виде XMLDOMNodeList. В том случае, если дочерних элементов нет, значение свойства length списка равно нулю . Только для чтения. lastChild Возвращает последний дочерний элемент или null, если таковых не имеется. Свойство доступно только для чтения. firstChild Возвращает последний дочерний элемент или null. Только для чтения. nextSibling Возвращает следующий дочерний элемент. Только для чтения. previousSibling Возвращает предыдущий дочерний элемент. Доступно только для чтения. parentNode Содержит ссылку на родительский элемент. В том случае, когда такого элемента нет, возвращает null. Доступно только для чтения. ownerDocument Возвращает указатель на документ, в котором находится текущий узел. Если в процессе модификации дерева узел будет перенесен в другой документ, то значение этого свойства автоматически изменится. Только для чтения. Методы Добавление новых элементов в объектную модель документа appendChild(newChild) Добавляет текущему узлу новый дочерний элемент. Возвращает ссылку на объект этого нового элемента. То же самое можно сделать и при помощи insertBefore (newChild, null) insertBefore(newChild, refChild) Вставляет дочерний узел, располагая его в текущем поддереве "левее" узла, указанного параметром refChild. Если последний параметр не задан, то новый узел будет добавлен в конец списка. Модификация и удаление узлов cloneNode (deep) Создание копии текущего элемента. Параметр deep определяет, будет ли эта процедура рекурсивно выполняться для всех дочерних элементов. Возвращаемое значение - ссылка на новый элемент replaceChild(newChild, oldChild) Замена объекта oldChild текущего списка дочерних объектов на newChild. Если newChild=null, то старый объект будет просто удален. removeChild(oldChild) Удаление объекта oldChild из списка дочерних элементов Поиск узлов (выделение поддеревьев) selectNodes(patternString) Возвращает объект XMLDOMNodeList, содержащий поддерево, выбранное по шаблону поиска patternString selectSingleNode(patternString) Аналогичен методу selectNodes, только возвращает первый узел из найденного поддерева Обработка поддеревьев стилевыми таблицами transformNode(stylesheet) Назначает стилевую таблицу XSL для поддерева текущего узла и возвращает строку - результат обработки. В качестве параметра передается ссылка на объект DOMDocument, в котором находятся XSL инструкции. transformNodeToObject(stylesheet, То же, что и transformNode, только результат - outputObject) обработанное дерево передается в объект XMLDocument(другое дерево), задаваемый параметром outputObject Объект XMLDOMNodeList Представляет собой список узлов - поддеревья и содержит методы, при помощи которых можно организовать процедуру обхода списка. Свойства length число элементов списка узлов item(i) Методы Выбор i-того элемента из списка. Возвращает объект XMLDOMNode nextNode() Выбор следующего элемента в списке. Если такого элемента нет, то возвращает null. первый вызов этого метода(после сброса итератора) возвратит ссылку на первый элемент списка. reset() Сброс внутреннего указателя текущего элемента Объект XMLDOMParserError Объект позволяет получить всю необходимую информацию об ошибке, произошедшей в ходе разбора документа. Все свойства этого объекта доступны только для чтения. Свойства errorCode Содержит код возникшей ошибки либо 0, если таковой не случилось. url Возвращает URL обрабатываемого документа filepos Возвращает смещение относительно начала файла фрагмента, в котором обнаружена ошибка line Содержит номер строки, содержащей ошибку linepos Позицию ошибки в строкев которой была обнаружена ошибка reason Описание ошибки srcText Содержит полный текст строки, в которой произошла ошибка Проверка правильности структуры и содержания документа XML Теперь у нас достаточно информации, чтобы программно организовать "контроль качества". Пример загрузки xml с проверкой на соответствие схеме приведен в директориях \xml\ex_dtd, \xml\ex_xdr, \xml\ex_xsd. Если в документе xml явно не прописана используемая схема, то её можно загружать и отдельно от документа и подсоединять к нему программно: var source = … //Создаем объект DOMDocument var schema = new ActiveXObject("Msxml2.XMLSchemaCache.4.0"); schema.add("http://filesystem.xsd/schema ","mySchema.xsd"); source.schemas = schema;