Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лек 016.doc
Скачиваний:
22
Добавлен:
07.02.2015
Размер:
79.36 Кб
Скачать

ЛЕКЦИЯ 16

XML. Объектная модель DOM XML. Парсер MSXML

Объекты данных: язык XML

Введение в язык XML

Что такое XML?

XML (eXtensible Markup Language) — это упрощенный диалект языка SGML, предназначенный для описания иерархических структур данных в World Wide Web. Он разрабатывается рабочей группой W3C с 1996 г.; в настоящее время принятой рекомендацией является вторая редакция языка XML 1.0 (октябрь 2000 г.), на которую и ориентируется дальнейшее изложение.

XML, несомненно, входит в обойму наиболее перспективных технологий WWW, чем объясняется интерес, который уделяется ему и корпорациями-разработчиками, и широкой публикой. Прежде чем перейти к его описанию, представляется уместным обсудить причины его появления и последующего бурного развития. Попытаемся для этого взглянуть на те проблемы WWW, которые должны быть решены средствами нового поколения Веб-технологий.

HTML не выражает смысла документов.

Язык HTML был создан для описания структурыдокументов (название, заголовки, списки, абзацы и т. п.) и, в некоторой степени, правил ихотображения(полужирный шрифт, курсивный шрифт и т. п.). Он ни в коей мере не предназначен для описаниясмысланаписанных на нем документов, а во многих случаях именно данные составляют существо документа, будь-то биржевая сводка или научная публикация. Поэтому появилась необходимость в языке описания данных, причем данных, организованных в иерархические структуры.

HTML громоздок и негибок.

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

Концепция Веб-обозревателя слишком ограничена.

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

Поиск документов возвращает слишком много ссылок.

Все мы постоянно пользуемся поисковыми системами и постоянно клянем их за неудобство работы. Допустим, что мне нужны все тексты книг Сергея Довлатова, имеющиеся в Сети. Попытка поиска по имени автора приведет к тому, что я получу список всех ссылок с этим именем, включая воспоминания о Довлатове, рецензии на его книги и т. д. Намного удобнее было бы воспользоваться специальным тегом <AUTHOR>, чтобы указать, что именно я ищу.

Невозможно найти взаимосвязанные ресурсы.

Допустим теперь, что я все же нашел несколько рассказов Довлатова, которые явно составляют единый сборник. Хорошо, если они содержат ссылку на оглавление, но часто это не так. Поэтому необходим способ указания того, что данная группа страниц составляет единый ресурс и должна обрабатываться соответственно. Для этого необходима стандартизованная и развитая система метаописателейВеб-страниц.

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

MathML — язык математических формул;

SMIL — язык интеграции и синхронизации мультимедийных средств;

SVG — язык двумерной векторной графики;

RDF — язык метаописаний ресурсов;

XHTML — переформулировка HTML в терминах XML.

Процесс обработки XML-документа состоит в следующем. Его текст анализируется специальной программой, которая называется XML-процессором. XML-процессор ничего не знает о семантике данных в документе; он только производит синтаксический разбор (parsing) текста документа и проверяет его правильность с точки зрени правил XML. Если документправильно оформлен(well-formed), то результаты разбора текста передаются XML-процессором прикладной программе, которая выполняет их содержательную обработку; если же документ оформлен неверно, т. е. содержит синтаксические ошибки, то XML-процессор должен сообщить о них пользователю.

8.1.2. Применения XML

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

Традиционная обработка данных

Перечисленные выше возможности позволяют рассматривать XML как платформо-независимый стандарт хранения и представления информации, который в сочетании с другими современными технологиями (в частности, с технологиями Java) способен стать основой для создания любых машинно-независимых приложений, в т. ч. для обмена данными между сервером и клиентом. Кроме того, активно разрабатываемые сегодня языки запросов на базе XML могут составить серьезную конкуренцию языку SQL.

Программирование, управляемое документом

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

Архивирование компонентов

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

Внедрение данных

После того, как мы определили структуру данных XML, принципиально несложно написать генератор кода, обрабатывающего эти данные. По мере развития подобных программных средств вся рутинная обработка данных (включая проверку их правильности, представление в нужном формате и т. п.) может быть автоматизирована, позволяя разработчикам сосредоточиться на нестандартных частях создаваемого продукта.

Структура XML-документа

XML-документ состоит из деклараций, элементов, комментариев, специальных символов и директив. Все эти составляющие документа описаны в данной главе.

8.1.3.1. Элементы и атрибуты

XML — это теговый языкразметки документов. Иными словами, любой документ на языке XML представляет собой наборэлементов, причем начало и конец каждого элемента обозначается специальными пометками, называемымитегами.

Элемент состоит из трех частей: начального тега, содержимого и конечного тега. Тег — это текст, заключенный в угловые скобки "<" и ">". Конечный тег имеет то же имя, что начальный тег, но начинается с косой черты "/". Пример XML-элемента:

<author>Сергей Довлатов</author>

Имена элементов зависят от регистра, т. е. <author>,<Author>и<AUTHOR>— это имена различных элементов. Наличие закрывающего тега всегда обязательно. Если тег являетсяпустым, т. е. не имеет содержимого и закрывающего тега, то он имеет специальную форму:

<элемент/>

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

имя_атрибута="значение_атрибута"

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

<author country="USA">Сергей Довлатов</author>

Элементы должны либо следовать друг за другом, либо быть вложены один в другой:

<books>

<book isbn="5887821192">

<title>Часть речи</title>

<author>Бродский, Иосиф</author>

<present/>

</book>

<book isbn="0345374827">

<title>Марш одиноких</title>

<author>Довлатов, Сергей</author>

<present/>

</book>

</books>

Здесь элемент books(книги) содержит два вложенных элементаbook(книга), которые, в свою очередь, имеют атрибутisbnи содержат три последовательных элемента:title(название),author(автор) иpresent(есть в наличии), причем последний пуст, т. к. в данном случае соответствует логическому флажку.

Из приведенного описания видно, что синтаксис XML напоминает синтаксис HTML (что естественно, т. к. оба они являются диалектами одного языка SGML), но требования к оформлению правильных XML-документов выше. Еще одним очень важным отличием XML от HTML является то, что содержимое элементов, т. е. все, что содержится между начальным и конечным тегами, считается данными. Это означает, что XML не игнорирует символы пробела и разрыва строк, как это делает HTML.

8.1.3.2. Пролог и директивы

Любой XML-документ состоит из прологаикорневого элемента, например:

<?xml version="1.0"?>

<books>

<book isbn="0345374827">

<title>Марш одиноких</title>

<author>Довлатов, Сергей</author>

<present/>

</book>

</books>

В этом примере пролог сводится к единственной директиве(первая строка документа), указывающей версию XML. За ней следует XML-элемент с уникальным именем, который содержит в себе все остальные элементы и называется корневым. Директива (processing instruction) — это выражение, заключенное в специальные теги "<?" и "?>", которое содержит указания программе, обрабатывающей XML-документ.

Стандарт XML резервирует только одну директиву <?xml version="1.0"?>, указывающую на версию языка XML, которой соответствует данный документ (второй версии XML пока нет). В действительности, эта директива несколько богаче и в самом общем виде выглядит так:

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>

Здесь атрибут encodingзадает кодировку символов документа. По умолчанию считается, что XML-документы должны создаваться в форматеUTF-8илиUTF-16. Если же используется какая-либо другая кодировка символов, то ее название согласноТаблицы П7.1должно быть указано в данном атрибуте, как показано в примере. Атрибутstandaloneговорит о том, содержит ли данный документвнешние разделы. Значениеyesозначает, что таких разделов нет, значениеno— что они есть.

В общем случае, пролог может содержать также декларации типа документа.

8.1.3.3. Комментарии

XML-документы могут содержать комментарии, которые игнорируются приложением, обрабатывающим документ. Комментарии строятся по тем же правилам, что и в HTML:

начинайте комментарий с символов "<!--",

завершайте комментарий символами "-->",

не используйте внутри комментария символов "--".

Пример комментариев:

<!-- это комментарий -->

<!-- а вот еще комментарий,

занимающий более одной строки -->

Имена и данные

Все именаэлементов, атрибутов и разделов должны начинаться с буквы Unicode и состоять из букв, цифр, символов точки (.), подчеркивания (_) и дефиса (-). Единственное ограничение состоит в том, что они не должны начинаться с комбинации букв xml в любом регистре; подобные имена зарезервированы для будущих расширений языка. Существенно, что стандарт допускает использование в именах не только английских букв, но и любых других, хотя существующие XML-процессоры часто ограничены теми системами кодировок, которые в них заложены создателями. Поэтому мы в своих примерах пишем имена по-английски.

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

Специальные символы

Ряд символов в языке XML зарезервирован и должен представляться специальным образом:

левая угловая скобка ("<")

<

правая угловая скобка (">")

>

амперсант ("&")

&

двойная кавычка (") в значениях атрибутов

"

одинарная кавычка (') в значениях атрибутов

'

При желании можно пользоваться числовой кодировкой символов в стандарте Unicode. При этом символ может быть задан своим десятичным кодом (&#код;) или шестнадцатеричным кодом (&#xкод;). Например©представляет символ авторского права©, аА– русскую буквуА. Как мы увидим в дальнейшем, XML гораздо богаче, чем HTML, в использовании подобных конструкций, поскольку позволяет осуществлять подстановку в текст документов любых символьных выражений.

Секции CDATA

Еще одним способом включения в содержимое XML-элементов недопустимых символов является использование т. н. секций CDATA(сокр. от Character DATA, т. е. символьные данные). Допустим, что мы хотим сделать содержимым элементаlayoutфрагмент HTML-текста, например:

<layout>

<H1>Заголовок</H1>

</layout>

Подобная конструкция неверна, т. к. HTML-тег H1будет в данном случае воспринят как тег XML. Для того, чтобы все содержимое элементаlayoutвоспринималось как данные, мы должны заключить его в секциюCDATA:

<layout>

<![CDATA[<H1>Заголовок</H1>]]>

</layout>

Как мы видим из этого примера, секция CDATA заключается в ограничители <![CDATA[ и ]]>. Все внутри этой секции считается символьными данными; в частности, секции CDATA не могут вкладываться друг в друга.

8.1.4. Разделы и их декларации

8.1.4.1. Разделы XML-документа

Физически XML-документ может состоять из несколько разделов(entities). При этом корневой элемент документа также является разделом, который называетсяразделом документа, хотя он никак специально не оформлен. Все разделы имеют содержимое; все они, кроме раздела документа и внешней DTD, имеют имя.

С точки зрения синтаксического разбора документа разделы подразделяются на анализируемые и неанализируемые. Неанализируемый раздел(unparsed entity) — это ресурс, содержимое которого XML-процессор воспринимает как внешние данные без их синтаксического анализа (например, текст, не являющийся XML-документом). Неанализируемые разделы всегда имеютнотацию, указывающую на их формат.Анализируемые разделы(parsed entities) предназначены для текстовой подстановки: всякий раз, когда XML-процессор встречает в документе имя такого раздела, он заменяет его на содержимое этого раздела.

8.1.4.2. Внутренние разделы

Декларации разделов подразделяются на внутренние и внешние. Декларация внутреннего разделавыглядит так:

<!ENTITY имязначение>

Она включает в себя содержимое объекта (параметр значение) и используется для подстановки этого значения вместо имени раздела. Мы можем, например, ввести в пример с книгами атрибутжанри использовать для задания жанра внутренние разделы:

<!DOCTYPE spec [

<!ENTITY pr "проза">

<!ENTITY po "поэзия">

]>

<books>

<book genre="&po;">

<title>Часть речи</title>

<author>Бродский, Иосиф</author>

</book>

<book genre="&pr;">

<title>Марш одиноких</title>

<author>Довлатов, Сергей</author>

</book>

</books>

Из этого примера видно, что ссылка на раздел(entity reference) выглядит точно так же, как ссылка на специальный символ, т. е. имеет вид&имя;. На самом деле, специальные символы — это точно такие же ссылки, но соответствующие разделы заданы неявно во внутренней декларации языка XML. Подобные текстовые подстановки удобны для задания сокращений, позволяющих уменьшить объем документа, и для введения обозначений для часто изменяемых полей документа. Так, например, мы можем вынести во внутренний раздел дату очередной ревизии публикации и затем изменять только значение этого раздела.

8.1.4.3. Внешние разделы

Существуют два варианта деклараций внешнего раздела:

<!ENTITY имя SYSTEM URI [NDATA нотация]?>

<!ENTITY имя PUBLIC строка? URI[NDATAнотация]?>

Первый вариант называется системным разделом, второй —публичным разделом. Они оба связывают имя раздела с внешним ресурсом, заданным своимURI, который должен иметькодированную формуи не содержатьзакладок. URI внешнего ресурса называетсясистемным идентификатором раздела. Использование внешнего ресурса зависит от нескольких факторов:

Если декларация содержит параметр NDATA, задающий нотацию раздела, то раздел является неанализируемым.

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

Публичный раздел может содержать строку, задающуюпубличный идентификатор раздела. XML-процессор может использовать этот идентификатор для генерации альтернативного URI данного раздела. Если ему это не удалось, то он должен использовать системный идентификатор для загрузки содержимого раздела.

Примеры деклараций внешних ресурсов:

<!-- неанализируемый ресурс: GIF-образ -->

<!ENTITY photo SYSTEM "images/photo.gif" NDATA gif>

<!-- системный анализируемый ресурс -->

<!ENTITY hatch SYSTEM "http://www.textuality.com/boilerplate/hatch.xml">

<!-- публичный анализируемый ресурс -->

<!ENTITY hatch PUBLIC "-//Textuality//TEXT Standard hatch boilerplate//EN"

"http://www.textuality.com/boilerplate/hatch.xml">

Внешний анализируемый раздел должен начинаться с директивы <?xml …?>, которая может не содержать номера версии, но обязана содержать кодировку символов. Эта директива не входит в состав подставляемого текста.

8.1.5. Декларация типа документа

Декларация типа XML-документа(document type declaration) содержитопределение типа документа(document type definition, DTD) или указывает на него. DTD — это специальная грамматика, описывающая синтаксис определенного класса документов; правила создания DTD рассмотрены вгл. 8.2. Здесь же приводится только описание деклараций, которые обеспечивают доступ к DTD. Декларация типа документа, как и декларация раздела, может быть внутренней или внешней. Внутренняя декларация имеет вид:

<!DOCTYPE имя[тело]>

а внешняя — те же два варианта, что и внешние разделы:

<!DOCTYPE имя SYSTEM URI [ тело ]>

<!DOCTYPE имя PUBLIC строка? URI[тело]>

Таким образом, отличие декларации типа документа от декларации раздела состоит только в том, что:

она начинается с ключевого слова !DOCTYPE, а не!ENTITY;

она может иметь тело, заключенное в квадратные скобки.

Имя такой декларации должно совпадать с именем корневого элемента, который она описывает, а тело должно соответствовать правилам построения DTD и будет описано в гл. 8.2. Пока отметим, что оно может содержать декларации разделов. Пример внутренней декларации был приведен вп. 8.1.4.2. Примеры внешних деклараций:

<!DOCTYPE spec SYSTEM "xml/1998/06/xmlspec-v20.dtd">

<!DOCTYPE spec PUBLIC "-//W3C//DTD Specification V2.0//EN"

"/XML/1998/06/xmlspec-v20.dtd">

Отметим, что внешняя декларация типа документа может содержать и ссылку на DTD, которая называется внешним подмножествомDTD, и тело, которое описывает дополнения к внешней DTD (оно называетсявнутренним подмножествомDTD).

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

Чтобы собрать все описанные выше понятия в единое целое, приведем пример законченного XML-документа, содержащего прейскурант книжного магазина.

<?xml version='1.0' encoding="windows-1251" standalone="yes"?>

<!DOCTYPE bookstore [

<!ENTITY po "поэзия">

<!ENTITY pr "проза">

<!ENTITY dr "драматургия">

]>

<!-- Этот файл содержит фрагмент базы данных книжного магазина -->

<bookstore>

<book genre="&pr;">

<title>Марш обреченных</title>

<author>

<first-name>Сергей</first-name>

<last-name>Довлатов</last-name>

</author>

<price>60.00</price>

</book>

<book genre="&po;">

<title>Часть речи</title>

<author>

<first-name>Иосиф</first-name>

<last-name>Бродский</last-name>

</author>

<price>55.00</price>

</book>

<book genre="&dr;">

<title>Антигона</title>

<author>

<name>Софокл</name>

</author>

<price>103.50</price>

</book>

</bookstore>

Сценарии объектной модели документа DOM XML средствами OLE-Automation

MS XML Parser как OLE-сервер

Библиотека MS XML Parser предоставляет возможность работы с XML-документами в скриптах, использующих объектную модель DOM XML. Такая работа возможна практически в любых средах, способных выступить в роли OLE-клиента. В данной статье примеры скриптов будут приводиться на языке VBScript для административных скриптов Windows. Вы можете копировать содержимое подобных примеров в текстовые файлы с расширением .vbs и запускать эти файлы на исполнение двойным щелчком мыши или из командной строки с помощью интерпретатора cscript.exe.

Объект DOMDocument создаётся следующим образом: Set xmlParser = CreateObject("Msxml2.DOMDocument")

После этого вы можете вызывать и использовать методы и свойства этого объекта для чтения и записи XML-документов. Примечание: методы объектов XMLDOMDocument и XMLDOMElement во многом сходны, поэтому рассматриваются в данной статье совместно. Описание свойств, методов и событий в данной статье не является полностью исчерпывающим. Полное описание объектной модели MS XML Parser вы можете получить в MSDN, воспользовавшись, например, поиском по словосочетанию "IXMLDOMDocument/DOMDocument Members" или "IXMLDOMElement Members".

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

В примерах кода, приведённых ниже, используется следующий "образцовый" XML-документ, представляющий из себя некий абстрактный упрощённый каталог товаров:

<?xml version="1.0"?>

<!DOCTYPE PRODUCTS

[

<!ELEMENT PRODUCTS (PRODUCT)*>

<!ELEMENT PRODUCT (TITLE, SORT+)>

<!ELEMENT TITLE (#PCDATA)>

<!ELEMENT COLOR (#PCDATA)>

<!ELEMENT PRICE (#PCDATA)>

<!ELEMENT SORT (COLOR, PRICE)>

<!ATTLIST PRODUCT import (yes | no) "no">

]

>

<PRODUCTS>

<PRODUCT import="yes">

<TITLE> Product #1 </TITLE>

<SORT>

<COLOR> red </COLOR>

<PRICE> $10.00 </PRICE>

</SORT>

<SORT>

<COLOR> blue </COLOR>

<PRICE> $11.00 </PRICE>

</SORT>

<SORT>

<COLOR> gray </COLOR>

<PRICE> $16.00 </PRICE>

</SORT>

</PRODUCT>

<PRODUCT>

<TITLE> Product #2 </TITLE>

<SORT>

<COLOR> red </COLOR>

<PRICE> $20.00 </PRICE>

</SORT>

<SORT>

<COLOR> green </COLOR>

<PRICE> $22.00 </PRICE>

</SORT>

</PRODUCT>

<PRODUCT import="yes">

<TITLE> Product #3 </TITLE>

<SORT>

<COLOR> red </COLOR>

<PRICE> $30.00 </PRICE>

</SORT>

<SORT>

<COLOR> blue </COLOR>

<PRICE> $33.00 </PRICE>

</SORT>

</PRODUCT>

<PRODUCT>

<TITLE> Product #4 </TITLE>

<SORT>

<COLOR> red </COLOR>

<PRICE> $40.00 </PRICE>

</SORT>

<SORT>

<COLOR> blue </COLOR>

<PRICE> $44.00 </PRICE>

</SORT>

</PRODUCT>

<PRODUCT>

<TITLE> Product #5 </TITLE>

<SORT>

<COLOR> red </COLOR>

<PRICE> $50.00 </PRICE>

</SORT>

<SORT>

<COLOR> gray </COLOR>

<PRICE> $55.00 </PRICE>

</SORT>

</PRODUCT>

</PRODUCTS>

Вот XSL-таблица стилей для вышеприведённого документа, которая также является обычным XML-документом:

<?xml version="1.0" encoding="windows-1251"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">

<xsl:template match="/">

<H1>Каталог товаров</H1>

<xsl:apply-templates select="PRODUCTS/PRODUCT" />

</xsl:template>

<xsl:template match="PRODUCT">

<SPAN style="font-style:italic">Наименование:</SPAN>

<xsl:value-of select="TITLE" /> <BR />

<SPAN style="font-style:italic">Импортный:</SPAN>

<xsl:value-of select="@import" /> <BR />

<TABLE border="1" width="100%" cellspacing="0">

<xsl:apply-templates select="SORT" />

</TABLE>

<BR />

</xsl:template>

<xsl:template match="SORT">

<TR>

<TD><xsl:value-of select="COLOR" /></TD>

<TD><xsl:value-of select="PRICE" /></TD>

</TR>

</xsl:template>

</xsl:stylesheet>

Загрузка XML-документа, отслеживание ошибок

Перечень свойств, методов и событий:

Описание

async

Булево. Чтение и запись. Истина, если разрешена асинхронная загрузка документа. По умолчанию - истина. Если свойство установлено в True, метод load вернёт управление раньше, чем загрузка будет завершена. В этом случае вы можете использовать свойство readyState для проверки состояния загрузки, обрабатывая событие onreadystatechange.

parsed

Булево. Только для чтения. Определяет состояние разборки узла и его дочерних узлов. В процессе асинхронного доступа в какой-то конкретный момент может оказаться доступным не все дерево документа. Перед выполнением некоторых операций, типа преобразований XSLT, полезно знать, доступно ли все дерево ниже этого узла для обработки.

parseError

Только для чтения. Возвращает ссылку на объект XMLDOMParseError, при помощи которого можно получить подробную информацию о последней ошибке анализатора.

readyState

Только для чтения. Возвращает целое число, характеризующее текущее состояние анализатора:

LOADING (1) - находится в процессе загрузки документа.

LOADED (2) - загрузка завершена, но объектная модель документа ещё не доступна.

INTERACTIVE (3) - объектная модель создана (все элементы разобраны, установлены их связи и атрибуты), но доступна пока только для чтения.

COMPLETED (4) - документ разобран, с ошибками или без.

resolveExternals

Булево. Чтение и запись. По умолчанию - истина. Определяет, должны ли быть разрешены во время разбора внешние определения - пространства имён, внешние подмножества DTD и ссылки на внешние примитивы, независимо от проверки на валидность. Если задано True, внешние определения разрешаются во время разбора. Это позволяет определить атрибуты по умолчанию и типы данных и использовать внешнее подмножество DTD. Эта установка независима от того, должна ли быть выполнена проверка на валидность (что задаётся значением свойства validateOnParse). Если внешнее определение не может быть разрешено в процессе разбора, происходит ошибка.

validateOnParse

Булево. Чтение и запись. По умолчанию - истина. Определяет, должен ли парсер проверить документ на валидность. Если установлено False, осуществляется только проверка на корректно сформированный (well-formed) документ.

abort()

Прерывание процесса асинхронной загрузки и обработки документа. Объект XMLDOMParseError будет содержать информацию об ошибке. Если загрузка уже завершена (свойство readyState равно 4), никакие действия не предпринимаются.

load(xmlSource)

Загружает документ, URL которого задан параметром xmlSource. В случае успеха возвращает True. Вызов этого метода обнуляет содержимое текущего документа. Если указанный URL не доступен или не ссылается на документ XML, этот метод возвращает ошибку и устанавливает свойство documentElement в null. Вы можете использовать этот метод, чтобы проверить, правильно ли построен (well-formed) документ XML. Вы не можете использовать этот метод, чтобы проверить документ на валидность.

loadXML(strXML)

Загружает XML-фрагмент из передаваемой строки. Вы можете использовать этот метод, чтобы проверить, правильно ли построен (well-formed) документ XML. Вы не можете использовать этот метод, чтобы проверить документ на валидность.

ondataavailable

Событие вызывается, когда обработчик обрабатывает очередную порцию данных документа. В обработчике этого события можно проверять текущий статус асинхронной загрузки (значение свойства readyState).

onreadystatechange

Событие вызывается каждый раз, когда изменяется состояние обработчика - значение свойства readyState.

Свойства объекта XMLDOMParseError (все свойства доступны только для чтения):

Описание

errorCode

Содержит код возникшей ошибки или нуль, если ошибки не случилось.

filepos

Содержит смещение относительно начала файла, в котором обнаружена ошибка.

line

Содержит номер строки, в которой обнаружена ошибка.

linepos

Содержит позицию ошибки в строке, в которой обнаружена ошибка.

reason

Содержит описание ошибки.

srcText

Содержит полный текст строки, в которой обнаружена ошибка.

url

Содержит URL обрабатываемого документа.

Пример скрипта, осуществляющего загрузку XML-документа с проверкой на ошибки:

'Создаём OLE-объект DOMDocument

Set xmlParser = CreateObject("Msxml2.DOMDocument")

'Отключаем асинхронную загрузку

xmlParser.async = False

'Загружаем XML-документ

xmlParser.load "C:\Sample.xml"

'Если случилась ошибка, выдаём информацию о ней и завершаем работу

If xmlParser.ParseError.ErrorCode Then

ShowError xmlParser.parseError

WScript.Quit

End If

'Выводим содержимое XML-документа

WScript.Echo xmlParser.xml

'Освобождаем объектную переменную

Set xmlParser = Nothing

'******************************************************************************

Function ShowError(XMLDOMParseError)

mess = _

"parseError.errorCode: " & XMLDOMParseError.errorCode & vbCrLf & _

"parseError.filepos: " & XMLDOMParseError.filepos & vbCrLf & _

"parseError.line: " & XMLDOMParseError.line & vbCrLf & _

"parseError.linepos: " & XMLDOMParseError.linepos & vbCrLf & _

"parseError.reason: " & XMLDOMParseError.reason & vbCrLf & _

"parseError.srcText: " & XMLDOMParseError.srcText & vbCrLf & _

"parseError.url: " & XMLDOMParseError.url & vbCrLf

WScript.Echo mess

End Function

Пример асинхронной загрузки XML-документа:

Set xmlParser = WScript.CreateObject("Msxml2.DOMDocument","xmlParser_")

xmlParser.load "C:\Sample.xml"

'******************************************************************************

Function xmlParser_onreadystatechange()

WScript.Echo "readyState = " & xmlParser.readyState

If xmlParser.readyState = 4 Then

WScript.Echo xmlParser.xml

End If

End Function

Обход дерева элементов

Перечень свойств и методов:

Описание

documentElement

Содержит узел, представляющий корневой элемент документа (объект XMLDOMElement). Чтение и запись. Возможно присвоение ссылки на другой объект созданного ранее документа.

childNodes

Содержит коллекцию (объект XMLDOMNodeList) всех дочерних узлов-неатрибутов данного узла. Только чтение.

firstChild

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

lastChild

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

nextSibling

Содержит следующий узел (любого типа) на том же уровне данного узла. Только чтение.

previousSibling

Содержит предыдущий узел (любого типа) на том же уровне данного узла. Только чтение.

parentNode

Содержит узел, для которого данный узел является дочерним (не действует для атрибутов). Только чтение.

ownerDocument

Содержит корневой узел документа, содержащего данный узел. Только чтение.

text

Содержит всё текстовое содержимое данного узла, включая подчинённые узлы. Чтение и запись.

xml

Содержит всё xml-содержимое данного узла, включая подчинённые узлы. Только чтение.

nodeValue

Содержит значение данного узла. Если компонент XML непосредственно не имеет значения, содержит null. Чтение и запись.

getElementsByTagName(typename)

Возвращает коллекцию XMLDOMNodeList всех элементов заданного типа. Если указано "*", возвращает все элементы.

attributes

Содержит коллекцию XMLDOMNamedNodeMap всех дочерних узлов-атрибутов данного узла. Только чтение.

getAttribute(name)

Возвращает значение атрибута с заданным именем.

getAttributeNode(name)

Возвращает узел атрибута с заданным именем.

Свойства и методы объекта-коллекции XMLDOMNodeList:

Описание

length

Количество элементов (узлов) в коллекции.

item(index)

Возвращает узел по заданному индексу. Отсчёт начинается с нуля. Данный метод является методом по умолчанию.

reset()

Устанавливает внутренний указатель на позицию перед первым узлом в наборе, чтобы следующий вызов nextNode() возвращал первый узел.

nextNode()

Возвращает следующий узел в наборе, в соответствии с позицией внутреннего указателя.

Коллекция XMLDOMNamedNodeMap помимо свойств и методов коллекции XMLDOMNodeList поддерживает методы:

Описание

getNamedItem(strName)

Возвращает узел, соответствующий атрибуту с заданным именем.

setNamedItem(newItem)

Добавляет переданный узел-атрибут в коллекцию (если атрибут с таким именем уже есть, замещает).

Перебор наименований товаров из образцового XML-документа:

Set xmlParser = CreateObject("Msxml2.DOMDocument")

xmlParser.async = False

xmlParser.load "C:\Sample.xml"

'Получаем корневой элемент (элемент PRODUCTS)

Set currNode = xmlParser.documentElement

'Получаем первый товар (элемент PRODUCT)

Set currNode = currNode.firstChild

'Перебор всех товаров (элементов PRODUCT)

While Not currNode Is Nothing

'Первый дочерний элемент товара - элемент TITLE,

'выводим его содержимое

WScript.Echo currNode.childNodes(0).text

'Содержимое дочернего узла типа "text" элемента TITLE -

'ещё один способ вывода наименования товара

WScript.Echo currNode.childNodes(0).childNodes(0).nodeValue

'Переходим к следующему товару (элементу PRODUCT)

Set currNode = currNode.nextSibling

Wend

Ещё один способ перебора наименований товаров из образцового XML-документа (используем коллекцию XMLDOMNodeList):

Set xmlParser = CreateObject("Msxml2.DOMDocument")

xmlParser.async = False

xmlParser.load "C:\Sample.xml"

'Получаем все заголовки товаров (элементы "TITLE")

Set colNodes = xmlParser.getElementsByTagName("TITLE")

'Устанавливаем внутренний указатель на позицию перед первым узлом в наборе

colNodes.reset

'Получаем первый заголовок (узел "TITLE")

Set nodeTitle = colNodes.nextNode

'Перебираем все заголовки (узлы "TITLE")

While Not nodeTitle Is Nothing

WScript.Echo nodeTitle.text

Set nodeTitle = colNodes.nextNode

Wend

Работаем с атрибутами. Выводим наименования только импортных товаров из образцового XML-документа:

Set xmlParser = CreateObject("Msxml2.DOMDocument")

xmlParser.async = False

xmlParser.load "C:\Sample.xml"

'Получаем все товары (элементы "PRODUCT")

Set colNodes = xmlParser.getElementsByTagName("PRODUCT")

'Перебираем все товары

For Each nodeProduct In colNodes

'Если товар импортный, выводим его наименование

If nodeProduct.getAttribute("import")="yes" Then

WScript.Echo nodeProduct.childNodes(0).text

End If

Next

Рекурсивный обход всего дерева элементов. Этот скрипт будет работать для любого XML-документа, в т.ч. для XSL-таблицы стилей, приведённой выше непосредственно после нашего "каталога товаров":

Set xmlParser = CreateObject("Msxml2.DOMDocument")

xmlParser.async = False

xmlParser.load "C:\Sample.xml"

'Запускаем рекурсию с корневого элемента (нулевой уровень)

ParseNode xmlParser.documentElement, 0

'******************************************************************************

Function ParseNode(nodeNode, numLevel)

'Выводим имя узла, а также его значение, если оно есть

If Not IsNull(nodeNode.nodeValue) Then

WScript.Echo Space(numLevel*4) & nodeNode.nodeName & " = " & _

Trim(nodeNode.nodeValue)

Else

WScript.Echo Space(numLevel*4) & nodeNode.nodeName

End If

'Выводим атрибуты узла, если они есть

If Not nodeNode.attributes Is Nothing Then

For Each nodeAttr In nodeNode.attributes

WScript.Echo Space((numLevel+1)*4) & nodeAttr.nodeName & _

" = " & nodeAttr.nodeValue

Next

End If

'Выводим рекурсивно дочерние узлы, если они есть

If nodeNode.childNodes.length > 0 Then

For Each nodeChild In nodeNode.childNodes

ParseNode nodeChild, numLevel+1

Next

End If

End Function

Получение информации о текущем узле дерева XML-документа

Перечень свойств:

Описание

nodeName

Содержит полное имя данного узла, включая префикс пространства имён. Только чтение.

baseName

Содержит имя данного узла без префикса пространства имён. Только чтение.

prefix

Содержит префикс (пространства имён) имени данного узла. Только чтение.

nodeType

Содержит тип текущего узла (число). Только чтение. Возможные значения:

NODE_ELEMENT(1) - элемент.

NODE_ATTRIBUTE(2) - атрибут.

NODE_TEXT(3) - текст.

NODE_CDATA_SECTION(4) - раздел CDATA.

NODE_ENTITY_REFERENCE(5) - примитив (ссылка в тексте).

NODE_ENTITY(6) - объявление примитива.

NODE_PROCESSING_INSTRUCTION(7) - инструкция по обработке.

NODE_COMMENT(8) - комментарий.

NODE_DOCUMENT(9) - корневой элемент документа.

NODE_DOCUMENT_TYPE(10) - описание типа документа (DTD).

NODE_DOCUMENT_FRAGMENT(11) - фрагмент XML-документа (несвязанное поддерево).

NODE_NOTATION(12) - нотация.

nodeTypeString

Содержит тип текущего узла (строка строчными буквами). Только чтение.

dataType

Содержит тип данных узла-атрибута, если этот тип данных определён в DTD. Чтение и запись.

namespaceURI

Содержит URI пространства имён текущего узла. Только чтение.

definition

Для узла типа "entityreference" содержит узел типа "entity" (т.е. его DTD-определение). Только чтение.

Рекурсивный обход всего дерева элементов с выводом информации о текущем узле. Этот скрипт будет работать для любого XML-документа, в т.ч. для XSL-таблицы стилей, приведённой выше непосредственно после нашего "каталога товаров":

Set xmlParser = CreateObject("Msxml2.DOMDocument")

xmlParser.async = False

xmlParser.load "C:\Sample.xml"

'Запускаем рекурсию с корневого элемента (нулевой уровень)

ParseNode xmlParser.documentElement, 0

'******************************************************************************

Function ParseNode(nodeNode, numLevel)

'Выводим данные об узле

WScript.Echo Space(numLevel*4) & nodeNode.nodeName & _

" (baseName = " & nodeNode.baseName & "," & _

" prefix = " & nodeNode.prefix & ")"

WScript.Echo Space(numLevel*4) & "(nodeType = " & nodeNode.nodeType & "," & _

" nodeTypeString = " & nodeNode.nodeTypeString & ")"

WScript.Echo Space(numLevel*4) & "(dataType = " & nodeNode.dataType & "," & _

" namespaceURI = " & nodeNode.namespaceURI & ")"

'Выводим рекурсивно атрибуты узла, если они есть

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]