Spec-Zone .ru
спецификации, руководства, описания, API
|
API StAX представляет методы для итеративной, основанной на событии обработки XML-документов. XML-документы обрабатываются как фильтруемая серия событий, и состояния инфонабора могут быть сохранены процедурным способом. Кроме того, в отличие от SAX, API StAX двунаправлен, включая и читая и пишущий XML-документов.
API StAX является действительно двумя отличными наборами API: API курсора и iterator API. Эти два набора API объясняются более подробно позже в этом уроке, но их основные функции кратко описываются ниже.
Поскольку имя подразумевает, API курсора StAX представляет курсор, с которым можно обойти XML-документ с начала до конца. Этот курсор может указать на одну вещь за один раз, и всегда продвигается, никогда назад, обычно один элемент инфонабора за один раз.
Двумя основными интерфейсами курсора является XMLStreamReader и XMLStreamWriter. XMLStreamReader включает методы средства доступа для всей возможной информации, восстановимой от модели Информации XML, включая кодирование документа, имена элементов, атрибуты, пространства имен, текстовые узлы, запускают теги, комментарии, обрабатывая инструкции, границы документа, и т.д; например:
public interface XMLStreamReader { public int next() throws XMLStreamException; public boolean hasNext() throws XMLStreamException; public String getText(); public String getLocalName(); public String getNamespaceURI(); // ... other methods not shown }
Можно вызвать методы на XMLStreamReader, такие как getText и getName, чтобы получить данные в текущей позиции курсора. XMLStreamWriter обеспечивает методы, которые соответствуют типам события StartElement И EndElement; например:
public interface XMLStreamWriter { public void writeStartElement(String localName) throws XMLStreamException; public void writeEndElement() throws XMLStreamException; public void writeCharacters(String text) throws XMLStreamException; // ... other methods not shown }
API курсора зеркально отражает SAX разными способами. Например, методы доступны для прямого доступа к строке и символьной информации, и целое число индексирует, может привыкнуть к атрибуту доступа и информации о пространстве имен. Как с SAX, методы API курсора возвращают информацию XML как строки, которая минимизирует объектные требования выделения.
StAX iterator API представляет поток XML-документа как ряд дискретных объектов-событий. Эти события вытягивает приложение и обеспечиваются синтаксическим анализатором в порядке, в котором они читаются в исходном XML-документе.
Основу iterator интерфейс вызывают XMLEvent, и есть подынтерфейсы для каждого типа события, перечисленного в таблице XMLEvent. Основным интерфейсом синтаксического анализатора для того, чтобы считать iterator события является XMLEventReader, и основной интерфейс для того, чтобы записать, что iterator событиями является XMLEventWriter. Интерфейс XMLEventReader содержит пять методов, самым важным из которых является nextEvent, который возвращает следующее событие в потоке XML. XMLEventReader реализует java.util.Iterator, что означает, что возвраты из XMLEventReader могут кэшироваться или переданы в подпрограммы, которые могут работать со стандартным Java Iterator; например:
public interface XMLEventReader extends Iterator { public XMLEvent nextEvent() throws XMLStreamException; public boolean hasNext(); public XMLEvent peek() throws XMLStreamException; // ... }
Точно так же на выходной стороне iterator API, Вы имеете:
public interface XMLEventWriter { public void flush() throws XMLStreamException; public void close() throws XMLStreamException; public void add(XMLEvent e) throws XMLStreamException; public void add(Attribute attribute) throws XMLStreamException; // ... }
Таблица: XMLEvent перечисляет типы XMLEvent, определенные в конечном счете iterator API.
Тип события |
Описание |
---|---|
StartDocument |
Сообщает начало ряда событий XML, включая кодирование, версию XML, и автономные свойства. |
StartElement |
Сообщает запуск элемента, включая любые атрибуты и объявления пространства имен; также обеспечивает доступ к префиксу, URI пространства имен, и локальному имени тега запуска. |
EndElement |
Сообщает конечный тэг элемента. Пространства имен, которые вышли из контекста, могут быть вспомнены здесь, если они были явно установлены на их соответствующем StartElement. |
Characters |
Соответствует XML разделы CData и объекты CharacterData. Отметьте, что об игнорируемом пробеле и существенном пробеле также сообщают как события Character. |
EntityReference |
О символьных объектах можно сообщить как дискретные события, которые разработчик приложений может тогда хотеть разрешать или проходить неразрешенный. По умолчанию объекты разрешаются. Альтернативно, если Вы не хотите сообщать об объекте как о событии, заменяющим текстом можно заменить и сообщен как Characters. |
ProcessingInstruction |
Сообщают цель и данные для базовой инструкции обработки. |
Comment |
Возвращает текст комментария. |
EndDocument |
Сообщает конец ряда событий XML. |
DTD |
Отчеты как информация о java.lang.String о DTD, если таковые вообще имеются, связанный с потоком, и обеспечивают метод для того, чтобы он возвратил пользовательские объекты, найденные в DTD. |
Attribute |
Об атрибутах обычно сообщают как часть события StartElement. Однако, есть времена, когда это является требуемым, чтобы возвратить атрибут как автономное событие Attribute; например, когда пространство имен возвращается как результат выражения XPath или XQuery. |
Namespace |
Как с атрибутами, о пространствах имен обычно сообщают как часть StartElement, но есть времена, когда это является требуемым, чтобы сообщить о пространстве имен как о дискретном событии Namespace. |
Отметьте, что DTD, EntityDeclaration, EntityReference, NotationDeclaration, и события ProcessingInstruction только создаются, если обрабатываемый документ содержит DTD.
Как пример того, как событие iterator API отображает поток XML, рассмотрите следующий XML-документ:
<?xml version="1.0"?> <BookCatalogue xmlns="http://www.publishing.org"> <Book> <Title>Yogasana Vijnana: the Science of Yoga</Title> <ISBN>81-40-34319-4</ISBN> <Cost currency="INR">11.50</Cost> </Book> </BookCatalogue>
Этот документ был бы проанализирован в восемнадцать основных и вторичных событий, как показано в следующей таблице. Отметьте, что к вторичным событиям, показанным в изогнутых фигурных скобках ({}), обычно получают доступ от основного события, а не непосредственно.
# |
Элемент/Атрибут |
Событие |
---|---|---|
1 |
version="1.0" |
StartDocument |
2 |
isCData = false data = "\n" IsWhiteSpace = true |
Characters |
3 |
qname = BookCatalogue:http://www.publishing.org attributes = null namespaces = {BookCatalogue" -> http://www.publishing.org"} |
StartElement |
4 |
qname = Book attributes = null namespaces = null |
StartElement |
5 |
qname = Title attributes = null namespaces = null |
StartElement |
6 |
isCData = false data = "Yogasana Vijnana: the Science of Yoga\n\t" IsWhiteSpace = false |
Characters |
7 |
qname = Title namespaces = null |
EndElement |
8 |
qname = ISBN attributes = null namespaces = null |
StartElement |
9 |
isCData = false data = "81-40-34319-4\n\t" IsWhiteSpace = false |
Characters |
10 |
qname = ISBN namespaces = null |
EndElement |
11 |
qname = Cost attributes = {"currency" -> INR} namespaces = null |
StartElement |
12 |
isCData = false data = "11.50\n\t" IsWhiteSpace = false |
Characters |
13 |
qname = Cost namespaces = null |
EndElement |
14 |
isCData = false data = "\n" IsWhiteSpace = true |
Characters |
15 |
qname = Book namespaces = null |
EndElement |
16 |
isCData = false data = "\n" IsWhiteSpace = true |
Characters |
17 |
qname = BookCatalogue:http://www.publishing.org namespaces = {BookCatalogue" -> http://www.publishing.org"} |
EndElement |
18 |
EndDocument |
Есть несколько важных вещей отметить в этом примере:
События создаются в порядке, в котором с соответствующими элементами XML встречаются в документе, включая вложение элементов, открываясь и закрываясь элементов, приписывают порядок, документ запускаются и конец документа, и т.д.
Как с надлежащим синтаксисом XML, у всех контейнерных элементов есть соответствующий запуск и события конца; например, у каждого StartElement есть соответствующий EndElement, даже для пустых элементов.
События Attribute обрабатываются как вторичные события, и получаются доступ от их соответствующего события StartElement.
Подобный событиям Attribute, события Namespace обрабатываются как вторичные, но появляются дважды и доступны дважды в конечном счете поток, сначала от их соответствующего StartElement и затем от их соответствующего EndElement.
События Character определяются для всех элементов, даже если у тех элементов нет никаких символьных данных. Точно так же события Character могут быть разделены через события.
Синтаксический анализатор StAX поддерживает стек пространства имен, который содержит информацию обо всех пространствах имен XML, определенных для текущего элемента и его предков. К стеку пространства имен, который представляется через интерфейс javax.xml.namespace.NamespaceContext, могут получить доступ префикс пространства имен или URI.
Разумно спросить в этой точке, “Что API я должен выбрать? Я должен создать экземпляры XMLStreamReader или XMLEventReader? Почему там два вида API так или иначе?”
Авторы спецификации StAX, предназначенной три типа разработчиков:
Библиотека и разработчики инфраструктуры: Создайте серверы приложений, JAXM, JAXB, JAX-RPC и подобные реализации; нуждаюсь в очень эффективных низкоуровневых API с минимальными требованиями расширяемости.
Разработчики ME Java: Нуждаюсь в небольших, простых, анализирующих получение по запросу библиотеках, и имею минимальные потребности расширяемости.
Платформа Java, Enterprise Edition (EE Java) и Платформа Java, Standard Edition (Java SE) разработчики: Должен убрать, эффективные анализирующие получение по запросу библиотеки, плюс потребность гибкость, чтобы и считать и записать потоки XML, создать новые типы события, и расширить элементы XML-документа и атрибуты.
Учитывая эти всесторонние категории разработки, авторы StAX чувствовали, что было более полезно определить два маленьких, эффективных API вместо того, чтобы перегрузить один больший и обязательно более сложный API.
Прежде, чем выбрать между курсором и iterator API, следует отметить несколько вещей, которые можно сделать с iterator API, который невозможно сделать с API курсора:
Объекты, создаваемые из подклассов XMLEvent, являются неизменными, и могут использоваться в массивах, списках, и картах, и могут быть переданы через Ваши приложения даже после того, как синтаксический анализатор шел дальше к последующим событиям.
Можно создать подтипы XMLEvent, которые являются или абсолютно новыми единицами информации или расширениями существующих элементов, но с дополнительными методами.
Можно добавить и удалить события из потока событий XML намного более простыми способами чем с API курсора.
Точно так же помните некоторые общие рекомендации, делая Ваш выбор:
Если Вы программируете для особенно ограниченной памятью среды, как ME Java, можно сделать меньший, более эффективный код с API курсора.
Если производительность является Вашим самым высоким приоритетом — например, создавая низкоуровневые библиотеки или инфраструктуру — API курсора более эффективен.
Если Вы хотите создать конвейеры обработки XML, используйте iterator API.
Если Вы хотите изменить поток событий, используйте iterator API.
Если Вы хотите, чтобы Ваше приложение было в состоянии обработать сменную обработку потока событий, используйте iterator API.
Вообще, если у Вас нет предпочтения strong так или иначе, используя iterator API рекомендуется, потому что это более гибко и расширяемо, таким образом "соответствуя требованиям завтрашнего дня" Ваши приложения.