1.2.3 DOM и SAX
1.2.3 DOM и SAX
Два наиболее популярных API, использующихся для разбора XML-документов, — это Объектная модель документа (Document Object Model, DOM) и Простой API для XML (Simple API for XML, SAX). DOM официально рекомендован W3C (рекомендация доступна по адресу http://www.w3.org/TR/REC-DOM-Level-1), тогда как SAX — это, фактически, стандарт, созданный Дэвидом Меггинсоном (David Megginson) и другими в подписке XML-DEV (http://lists.xml.org/archives). Мы кратко поговорим здесь об этих двух API. Мы не будем использовать их в этой книге, но они дадут вам понимание того, как работают большинство XSLT-процессоров.
Посетите http://www.megginson.com/SAX/ для получения информации о стандарте SAX (убедитесь, что аббревиатура SAX в адресе набрана большими буквами). Если вы хотите узнать больше об XML-DEV, отправьте e-mail с текстом «subscribe xml-dev» в теле письма на majordomo@xml.org. Вы также можете посетить http://www.lists.ic.ac.uk /hypermail/xml-dev для ознакомления с архивами рассылки.
1.2.3.1 DOM
DOM разработан для построения дерева XML-документа. Вспомните, что все XML-документы должны быть заключены в единственный XML-элемент, этот единственный элемент становится корнем дерева.
Спецификация DOM определяет несколько характерных сущностей, описанных здесь:
- Узел (node)
Эта сущность — основной тип данных в XML. Элемент (element), документ (document), текст (text) и атрибут (attr) — подходят под сущность «узел». - Документ (document)
Этот объект включает DOM-представление XML-документа. Имея доступ к Документу, вы можете получить корневой элемент (root) дерева; от корневого элемента вы можете проходить по дереву, чтобы искать элементы, атрибуты, текст, комментарии, исполнительные инструкции и т.п. в XML-документе. - Элемент (element)
Эта сущность представляет элемент в XML-документе. - Атрибут (attr)
Эта сущность представляет атрибут элемента в XML-документе. - Текст (text)
Эта сущность представляет кусочек текста из XML-документа. Любой текст в вашем XML-документе становится текстовым узлом (text node). Это значит, что текст DOM-объекта является его ребёнком, а не свойством. Текст в Элементе представляется как текстовый ребёнок объекта Элемент; текст Атрибута представляется точно так же. - Комментарий (comment)
Эта сущность представляет комментарий в XML-документе. Комментарий начинается с <!-- и заканчивается -->. Единственное ограничение для его содержания — это то, что два последовательных дефиса могут появиться только в начале и в конце комментария. В других местах комментарий может включать угловые скобки (< >), амперсанд (&), одинарные или двойные кавычки или что-то другое. - Управляющие инструкции (ProcessingInstruction, PI)
Эта сущность представляет управляющие инструкции в XML-документе. Управляющие инструкции выглядят следующим образом:Управляющие инструкции содержат информацию, предназначенную для процессора. Первая из двух PI (PI — это XML-жаргон, можете свободно обронить это в неофициальном разговоре, чтобы припечатать ваших друзей) — это стандартный способ связать XSLT-стили с XML-документом (подбробнее об этом — через минутку). Вторая PI используется Cocoon`ом, средой публикации контента на основе XML от Apache. (Если вы не знакомы с Cocoon, взгляните на его страницу http://xml.apache.org/cocoon.)<?xml-stylesheet href="case-study.xsl" type="text/xsl"?>
<?cocoon-process type="xslt"?>
Когда вы разбираете XML-документ при помощи DOM-парсера, он:
- Создаёт объекты (элменты, атрибуты, текст, комментарии), представляющие содержание документа. Эти объекты соответствуют сущностям (интерфейсам), определённым в спецификации DOM.
- Организовывает эти объекты в дерево. Каждый элемент в XML-документе имеет некоторые свойства (такие как имя элемента) и может также иметь потомков.
- Анализирует весь документ до того как вернуть вернуть управление вашему коду. Это означает. что для больших документов имеет место значительная задержка пока документ анализируется.
Самый важный факт о DOM состоит в том, что он основан на представлении вашего документа в виде дерева. XSLT-процессор использует очень похожее дерево-представление (с некоторыми незначительными различиями, такими как обстоятельство, что не всё, с чем мы имеем дело в XPath и XSLT имеет один и тот же корневой элемент). Понимание, как работает DOM-парсер, поможет легче понять, как XSLT-процессор видит ваш XML-документ.
1.2.3.1.1 Пример XML-дерева
И DOM, и XSLT, и XPath используют древовидную структуру данных XML-документа. По этой причине очень важно располагать минимальными общими знаниями о том, как DOM строит деревовидную структуру. Наш предыдущий документ с почтовыми индексами показан на рисунке 1−2:

Если мы хотим найти различные части нашего XML-документа, отсортировать вложенные деревья, основываясь на первой букве текста элемента <postalcode>, или выделить только те части, в которых текст элемента <usage-count> имеет числовое значение больше 500, нам нужно начать с верха DOM-дерева и двигаться вниз через потомков корневого элемента. Когда мы пишем XSLT-преобразование, мы также начинаем с корня дерева и двигаемся вниз.
1.2.3.2 SAX
SAX (Simple API for XML) был разработан Дэвидом Мэгинсоном (David Megginson) и другими в рассылке XML-DEV. У него есть несколько важных отличий от DOM:
- SAX API интерактивно. Когда SAX-парсер обрабатывает ваш документ, он посылает события вашему коду. Вам не нужно ждать, пока парсер доберётся до конца документа, как это обстоит с DOM; вы получаете события от парсера немедленно. Эти события позволяют вам узнавать, когда парсер находит начало документа, начало элемента, некоторый текст, конец элемента, управляющие инструкции, конец документа и т.д.
- SAX разработан так, чтобы избежать большого объёма памяти, используемого DOM. В SAX-мире вам сообщат, когда парсер встречает сущность в XML-документе; сохранить эту информацию — ваша забота. Если вы ничего не делаете, чтобы сохранить найденную парсером информацию, это идёт в мусорку.
- SAX не предоставляет иерархический вид документа, как это делает DOM. Если вам нужно знать больше о структуре XML-документа и о контексте данного элемента, SAX не многим вам поможет. Каждое SAX-событие неконтекстно; это значит, что SAX событие не скажет вам «Здесь есть некоторый текст в элементе <postalcode>, упомянутом мною ранее». SAX-парсер только скажет ам «Здесь есть текст». Если вам нужно больше знать о структуре XML-документа, вам следует хранить путь этой информации самостоятельно.
Лучшая штука в SAX — интерактивность. Большинство преобразований, в настоящее время делаемых при помощи XSLT, происходят на сервере. Со времен его возниконовения, большинство XSLT-процессоров основаны на DOM-парсерах. Хотя, в ближайшем будущем мы увидим XSLT-процессоры, базирующиеся на SAX-парсерах. Это означает, что процессор может начать выдавать результат почти одновременно с началом разбора исходного документа, обеспечивая в итоге лучшую пропускную способность и создавая ощущение более быстрой обработки. Так как и DOM, и XPath, и XSLT используют деревья для представления документов, DOM более важен для нашего здешнего обсуждения. Тем не менее, полезно знать, как работает SAX-парсер, особенно когда SAX-процессоры начнут поднимать свои маленькие быстрые головки.