 | Уровень сложности: средний Нейл Грэхэм (Neil Graham), Менеджер, XML Parser Development, IBM Елена Литани (Elena Litani), Разработчик программного обеспечения, IBM
09.11.2004 XML-технология неожиданно быстро становится зрелой. Недавно вышедший Java API for XML Processing (JAXP) 1.3 является проводником, при помощи которого многие новейшие открытые стандарты, связанные с XML, будут проникать в платформу J2SE. В этой статье, посвященной JAXP 1.3 API и состоящей из двух частей, ее авторы Neil Graham и Elena Litani приводят краткий обзор JAXP-спецификации, детальную информацию об изменениях в пакете javax.xml.parsers и описывают мощную среду кэширования схем и проверки корректности.
Первоначально JAXP 1.0 означал аббревиатуру для Java API for XML Parsing и просто предоставлял независимое от поставщика средство построения синтаксического анализатора DOM Level 1 или SAX 1.0. С появлением JAXP 1.1 в 2001, буква "P" стала обозначать Processing, а не Parsing, и функции API расширились также на предоставление стандартизированного средства взаимодействия приложений с XSLT-процессором. JAXP 1.1 стал частью как Java 2 Standard Edition (J2SE) 1.4, так и Java 2 Enterprise Edition (J2EE) 1.3. JAXP 1.2 появился в 2002 как небольшая ревизия спецификации; в эту версию была добавлена поддержка стандартизированного средства инициирования проверки корректности W3C XML Schema в совместимых с JAXP анализаторах.
JAXP 1.3, который будет частью J2SE 5 и J2EE 4, является первой новой версией этого API за три года. В этих двух статьях мы изучим каждую из новых функциональных возможностей, добавленных в JAXP этой новой версии.
Обзор JAXP 1.3
Спецификация JAXP поддерживает и основывается на следующих спецификациях (см. раздел "Ресурсы"):
- XML 1.0 (3rd Edition) и XML 1.1, W3C Recommendations.
- Namespaces in XML 1.0 (включая Errata) и Namespaces 1.1, W3C Recommendations.
- XML Schema (включая Errata), W3C Recommendation.
- XSL Transformations (XSLT) Version 1.0, W3C Recommendation.
- XML Path Language (XPath) Version 1.0 (включая Errata), W3C Recommendation.
- XML Inclusions (XInclude) Version 1.0, W3C Proposed Recommendation на момент написания статьи.
- Simple API for XML (SAX) 2.0.2 (sax2r3) и SAX Extensions 1.1.
Все совместимые с JAXP 1.3 реализации должны поддерживать перечисленные выше спецификации.
JAXPAPI содержит несколько пакетов Java, каждый из которых обеспечивает определенную функциональность JAXP:
javax.xml: Это основной пакет. Он содержит только один класс (XMLConstants), определяющий полезные константы.
javax.xml.parsers: Этот пакет существует, начиная с версии JAXP 1.0. В нем определяется не зависимый от поставщика API для синтаксического анализа и контроля корректности XML-документов с использованием SAX или DOM.
javax.xml.transform: Этот пакет существует, начиная с версии JAXP 1.1. В нем определен API for XSL Transformations.
javax.xml.namespace: Это новый пакет, добавленный в JAXP 1.3. Он определяет класс QName и интерфейс NamespaceContext, позволяющий управлять пространствами имен. Эти классы первоначально были определены в спецификации Java API for XML-Based RPC (JAX-RPC) (см. раздел "Ресурсы").
javax.xml.datatype: Это новый пакет, добавленный в JAXP 1.3. Он определяет новые типы Java для полного отображения между типами данных W3C XML Schema и типами Java.
javax.xml.validation: Это новый пакет, добавленный в JAXP 1.3. Он определяет API, позволяющий приложениям кэшировать схемы (например, W3C XML Schemas) и использовать их для проверки корректности XML-документов.
javax.xml.xpath: Это новый пакет, добавленный в JAXP 1.3. Он определяет независимый от реализации и модели данных API для применения в документах XPath-выражений.
JAXPтакже содержит пакет org.xml.sax, в котором находится SAX API, и пакет org.w3c.dom, в котором содержится DOM Level 3 API (см. раздел "Ресурсы").
JAXP1.3 и синтаксический анализ XML
Начиная с самых ранних версий, JAXP-спецификации, также как и лежащие в их основе спецификации XML и XML Namespaces, были привязаны к конкретным версиям DOM и SAX для гарантии максимальной переносимости построенных на их основе приложений. За три года, прошедших с момента выпуска последней основной версии JAXP (JAXP 1.1), ни одна из этих спецификаций не оставалась статичной. JAXP1.3 основан на самых последних версиях каждой из этих спецификаций, позволяя им пройти свой путь к J2SE и J2EE.
Эволюция стандартов XML
W3C завершил XML 1.0 3rd Edition, XML 1.1, и XML Namespaces 1.1 в начале 2004. JAXP 1.3 требует реализации всех трех спецификаций в совместимых синтаксических анализаторах. В то время как XML 1.0 3rd Edition содержит главным образом разъяснения, которые будут замечены только самыми изощренными XML-приложениями, XML 1.1 должна иметь большое позитивное влияние на мир XML благодаря значительному расширению количества символов, которые могут использоваться в XML-именах. Это достигается прямой совместимостью XML с Unicode Standard, приведением XML и Unicode к общим знакам конца строки и предоставлением включения ссылок на все символы ASCII за исключением 0 (включая все управляющие символы). XML Namespaces 1.1 разрешает префиксам пространства имен не быть объявленными внутри фрагментов документа, что, естественно, соответствует XML 1.1. Дополнительную информацию по этим спецификациям вы можете получить в статье developerWorks "XML 1.1 and Namespaces 1.1 revealed."
Еще одним продуктом консорциума W3C является XML Inclusions (XInclude) 1.0, в данный момент находящаяся в стадии Proposed Recommendation. XInclude обеспечивает средства, при помощи которых XML-документы могут включать в себя полностью или частично другие XML-документы и текстовые ресурсы. В отличие от XML-сущностей это делается полностью вне среды Document Type Definitions (DTD), и, таким образом, является удобным для проверки корректности XML Schema. Это также сделано и ради пространства имен. Авторы XML-ресурсов с содержимым, общим для многих документов, найдут XInclude бесценным. JAXP 1.3 обеспечивает соответствие всех совместимых реализаций этой спецификации еще до того, как она получит статус W3C Recommendation.
Что касается собственно API синтаксического анализа XML, JAXP поддерживает SAX 2.0.2 и SAX Extensions 1.1, а также DOM Level 3 Core и DOM Level 3 Load and Save. Спецификации DOM Level 3 сами по себе представляют значительную часть новой функциональности, поэтому их рассмотрение выходит за рамки данной статьи. На сайте developerWorks уже присутствуют замечательные статьи по DOM Level 3 Core (см. раздел "Ресурсы"), к которым может обратиться заинтересованный читатель.
Как и каждое незначительное изменение в номере версии, SAX 2.0.2 не отличается радикально от SAX 2.0, который поддерживался в JAXP 1.1. SAX 2.0.1 содержала некоторое количество изменений в совместимости сигнатур (что мешало ее поддержке в JAXP 1.2), таких как добавление конструкторов по умолчанию в определенных в SAX классах exception и добавление IOExceptions в предложение throws обратного вызова EntityResolver#resolveEntity - иначе она была бы фактически идентичной SAX 2.0. Среди других нововведений SAX 2.0.2 определяет:
- Функцию, позволяющую приложению спросить SAX-анализатор о том, поддерживает ли он XML 1.1.
- Функцию, указывающую синтаксическому анализатору включить XML-имена и пространства имен в JVM. Для определения равенства String и этих строк вы можете использовать знак
== вместо String.equals().
- Функцию, разрешающую проверку XML 1.1 нормализации. Отметим, что JAXP 1.3 не требует поддержки этой функции от совместимых анализаторов.
Спецификация Extensions 1.1 представляет собой значительное улучшение оригинальных расширений SAX. Вот некоторые из нововведений:
- Интерфейс
EntityResolver2 расширяет EntityResolver, обеспечивая обратный вызов для внешнего подмножества DTD, а также добавляет baseURI и имя сущности в список параметров метода resolveEntity.
Attributes2 расширяет Attributes, обеспечивая такую информацию как: объявлен ли каждый атрибут в DTD, или является ли значение атрибута значением, определенным в DTD по умолчанию.
Locator2 расширяет Locator, добавляя getXMLVersion() и getEncoding(). Это обеспечивает полный доступ к псевдо-атрибутам обрабатываемой в данный момент времени сущности в XML-определении.
Улучшения функциональности javax.xml.parsers
Изменения в относящихся к синтаксическому анализу интерфейсах, которые прямо определяются в JAXP 1.3, не являются слишком значительными. Возможно, самым полезным в общем случае является включение метода reset(), который добавлен как в DocumentBuilder, так и в SAXParser, и который дает возможность возвратить эти объекты в их первоначальное состояние. Поскольку механизм JAXP factory для объектов синтаксического анализатора очень требователен к ресурсам, приложения часто реализуют пул объектов SAXParsers и DocumentBuilders, который делает доступными эти объекты при возникновении задачи синтаксического анализа и не удаляет их после ее завершения. Способность сбросить эти объекты в известное состояние позволяет таким пулам не отслеживать использование объектов нуждающимся в них кодом, и не требует от кода, использующего несколько синтаксических анализаторов, никаких знаний о предыдущем использовании анализатора, к которому был получен доступ. Это должно сделать применение таких пулов значительно более эффективным и простым в реализации. Пример реализации пула синтаксического анализатора вы можете найти в статье "Улучшение производительности ваших XML-приложений, часть 2".
Вы можете подсоединяться к синтаксическим анализаторам со схемами (см. обсуждение пакета javax.xml.validation ниже) при помощи метода setSchema(), добавленного к SAXParserFactory и DocumentBuilderFactory. Это дает возможность проектировать оптимизированные под конкретную схему анализаторы (javax.xml.validation.Schemas), что, в свою очередь, значительно увеличивает производительность по сравнению со стандартными объектами анализаторов, не имеющих встроенных знаний о грамматике, согласно которой они могли бы быть использованы для проверки корректности документов. Приложения также могут настроить свои конструкторы синтаксических анализаторов для производства анализаторов, умеющих работать с XInclude при помощи методов get/setXIncludeAware. И анализаторы и конструкторы могут получить запрос о том, поддерживают ли они XInclude, при помощи метода isXIncludeAware(). Связанная с ними в данный момент времени (если есть) Schema может быть получена при помощи метода getSchema().
 |
Validation and Schema caching JAXP API
Многие приложения стремятся провести проверку корректности XML-документов по определенной схеме, например схеме, определенной в W3C XML Schema Recommendation. Для этого процессор проверки корректности должен проанализировать схему документа, представить эту схему в памяти и, затем, использовать эту схему в памяти для проверки корректности XML-документа. Следовательно, такая проверка корректности может привести к значительной потере производительности, если процессор будет производить синтаксический анализ и строить схему в памяти перед обработкой каждого XML-документа. Обычно приложение использует ограниченный набор схем, и поэтому было бы желательно, чтобы процессор строил представление конкретной схемы в памяти только один раз и использовал его для проверки документов.
До настоящего времени приложения должны были обеспечивать свой собственный механизм кэширования схем. Например, анализатор Apache Xerces-J определяет собственный API кэширования грамматики (см. раздел "Ресурсы"). Теперь JAXP 1.3 определяет стандартный API (пакет javax.xml.validation), дающий приложениям возможность повторно использовать схемы и, таким образом, повысить общую производительность.
Рассмотрим API проверки корректности. Для извлечения внутреннего представления схемы или схем прежде всего необходимо получить экземпляр конструктора схемы (javax.xml.validation.SchemaFactory), который указывает конкретный язык схемы, поддерживаемый данным конструктором. Совместимые с JAXP реализации должны поддерживать W3C XML Schema. Поддержка других языков, например RELAX NG, является не обязательной. Вы можете настроить конструктор при помощи функций и свойств аналогично настройке синтаксического анализатора XML и, в завершение, вы можете указать конструктору построить представление данной схемы (или схем) в памяти. Это внутренне представление схемы определено в виде класса Schema, являющегося неизменяемым и, следовательно, безопасным с точки зрения поддержки многопоточности (thread-safe). API не предоставляет средств для разрешения запросов о структуре или свойствах схемы.
Вы можете использовать класс Schema несколькими способами:
- Можно построить синтаксические анализаторы, которые оптимизированы по занимаемой памяти для использования конкретной Schema (как упоминалось ранее).
- Использовав класс Schema, вы можете создать валидаторы, которые могут проверять корректность различных источников XML-данных (таких как DOM or SAX).
Для начала мы рассмотрим, как улучшить производительность синтаксического анализа путем повторного использования внутреннего представления определенной схемы в памяти. Ради простоты в приведенном в листинге 1 примере используется XML-документ (po.xml), содержащий заказ на поставку и схему заказа (po.xsd). И документ, и схема определены с использованием W3C XML Schema Primer Recommendation (см. раздел "Ресурсы").
Постройте конструктор схемы и используйте его для создания внутреннего представления в памяти схемы заказа на поставку. Затем получите экземпляр DOM-конструктора и назначьте конструктору схему заказа. Создайте DOM-анализатор при помощи DOM-конструктора. Новый синтаксический анализатор будет способен производить проверку корректности XML-документов только в соответствии со схемой заказа на поставку.
Листинг 1. Повторное использование Schema для синтаксического анализа и проверки корректности XML-документов
// создание SchemaFactory, соответствующего W3C XML Schema
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
// назначение вашего обработчика ошибок во время построения схемы
sf.setErrorHandler(myErrorHandler);
// анализ схемы заказа на поставку
Schema schema = sf.newSchema("po.xsd");
// получение DOM-коструктора
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// настройка конструктора
dbf.setNamespaceAware(true);
// назначение схемы конструктору
dbf.setSchema(schema);
// создание нового анализатора, проверяющего документы
// согласно указанной схеме (po.xsd)
DocumentBuilder db = dbf.newDocumentBuilder();
// назначение обработчика ошибок, возникающих при проверке корректности документа
db.setErrorHandler(myErrorHandler);
// синтаксический анализ и проверка корректности XML-документа согласно po.xsd
Document purchaseOrderDoc = db.parse("po.xml");
|
Теперь рассмотрим, как можно использовать валидаторы. Из данной Schema можно создать два типа валидаторов:
- Validator способен проверять корректность как DOM так и SAX источников данных, по желанию генерируя DOM или SAX-события соответственно.
- ValidatorHandler проверяет корректность SAX-событий. Этот валидатор работает как SAX
ContentHandler. Если вы назначите свой собственный org.xml.sax.ContentHandler обработчику, ValidatorHandler будет действовать как фильтр входящих SAX-событий и перенаправлять события в ваш ContentHandler. Этот валидатор также предоставляет возможность получать информацию о типе элементов и атрибутов при помощи интерфейса TypeInfoProvider (см. метод ValidatorHandler.getTypeInfoProvider()).
Ни один из этих валидаторов не является безопасным с точки зрения поддержки многопоточности Они могут изменять выходные данные, дополняя оригинальные данные некоторой дополнительной информацией. Например, в результате проверки корректности в древовидной структуре DOM могут появиться новые атрибуты или возникнуть новые SAX-события. Вы можете установить различные функции и свойства для настройки валидаторов, зарегистрировать распознаватель сущностей (org.w3c.dom.ls.LSResourceResolver), который поможет валидатору распознавать любые внешние сущности, или назначить обработчик ошибок (org.xml.sax.ErrorHandler). Отметим, что если обработчик ошибок не назначен, реализация по умолчанию сгенерирует исключительную ситуацию SAXParseException при любой ошибке проверки корректности.
В листинге 2 приведен пример использования интерфейса Validator для проверки корректности DOM-документов. В этом случае предполагается, что вашему приложению нужно проверить корректность DOM-документов на соответствие двум типам схем: po.xsd и ipo.xsd. Приложение может получить DOM-документ из другого приложения, либо произвести некоторую модификацию существующего документа; при этом нужно убедиться , что документ все еще соответствует схемам po.xsd или ipo.xsd.
Листинг 2. Использование интерфейса Validator для проверки корректности DOM-документов
// создание источников JAXP-преобразования для указания
// желаемых схем
StreamSource po = new StreamSource("po.xsd");
StreamSource ipo = new StreamSource("ipo.xsd");
// внутреннее представление в памяти для po.xsd и ipo.xsd
Schema schemas = sf.newSchema(new Source[]{po, ipo});
// создание валидатора, способного проверять корректность
// на соответствие po.xsd и ipo.xsd
Validator validator = schemas.newValidator();
// настройка валидатора
validator.setErrorHandler(myErrorHandler);
// назначение древовидной структуры DOM, которую нужно проверить
DOMSource docSource = new DOMSource(purchaseOrderDoc);
// проверить корректность источника
validator.validate(docSource, null);
|
Заключение
В данной статье мы сделали общий обзор JAXP API, включая описание версий базовых XML-стандартов и модификации в API синтаксического анализа. Также детально был описан новый пакет javax.xml.validation и средства, которые он предлагает для улучшения производительности синтаксического анализа XML-данных. Во второй части мы рассмотрим предложенную в JAXP 1.3 поддержку новых типов данных, некоторые из общих инструментов по поддержке пространства имен, изменения в пакете javax.xml.transform и новый пакет javax.xml.xpath с его независимым от поставщиков и моделей данных XPath 1.0 API.
Ресурсы
- Оригинальная статья What's new in JAXP 1.3? Part 1 в формате PDF
- Найдите дополнительную информацию по Java API for XML Processing (JAXP).
- Найдите все спецификации W3C на Web-странице W3C Technical Reports.
- XML-документ po.xml и схема заказа на поставку po.xsd определены в W3C XML Schema Primer Recommendation.
- Прочтите о Java API for XML-Based RPC (JAX-RPC).
- Прочтите о спецификациях Simple API for XML (SAX) и Document Object Model (DOM).
- Проверьте две статьи по DOM Level 3 Core, написанные Еленой Литани (Elena Litani) и Арнодом Ле Хорсом (Arnaud Le Hors):
- В части 1 исследуются управление и сравнение узлов, а также обработка текста и пользовательских данных (developerWorks, август 2003).
- В части 2 исследуются автоматическая установка, отображение в XML Infoset, доступ к информации о типе и работа с Xerces (developerWorks, август 2003).
- Узнайте, о чем говорится в XML 1.1 и Namespaces 1.1, какие изменения они несут и как они влияют на другие спецификации и на работу пользователей, в статье "XML 1.1 and Namespaces 1.1 revealed", написанную Arnaud Le Hors (developerWorks, май 2004).
- Просмотрите все статьи серии "Улучшение производительности ваших XML-приложений " (часть 1 (июль 2004), часть 2 (июль 2004) и часть 3 (сентябрь 2004)) - на сайте developerWorks, чтобы узнать, как можно получить больше от ваших XML-приложений.
- Изучите синтаксический анализатор Java Xerces2 и его API кэширования грамматики.
- Внимательно рассмотрите RELAX NG, который поддерживается Organization for the Advancement of Structured Information Standards (OASIS) и является стандартом как OASIS, так и International Organization for Standardization (ISO).
- Запутались во всех этих XML-стандартах? Серия статей Uche Ogbuji по XML-стандартам на developerWorks поможет в них разобраться:
- Часть 1 – Базовые стандарты (январь 2004)
- Часть 2 – Стандарты обработки XML (февраль 2004)
- Часть 3 – Важнейшая терминология (февраль 2004)
- Часть 4 – Детальный обзор взаимодействия самых важных XML-стандартов (март 2004)
- Найдите другие ресурсы по этой теме на сайте developerWorks в зонах технологий XML и Java.
- Узнайте, как можно стать IBM Certified Developer в сфере XML и сопутствующих технологий.
Об авторах  | |  | Нейл Грэхэм (Neil Graham) - является менеджером отдела XML Parser Development в IBM. Он работает над синтаксическими анализаторами Apache Xerces-Java и Xerces-C++ XML, в частности, среди прочего, над реализацией XML Schema, XML 1.1 и кэширования грамматики. Он также был одним из представителей IBM в Expert Group, которая разработала JAXP 1.3. |
 | |  | Елена Литани (Elena Litani) - разработчик программного обеспечения в IBM. Она является одним из основных участников проекта Eclipse Modeling Framework (EMF) на Eclipse.org, который предоставляет рекомендованную реализацию для Service Data Objects (SDO). Ранее Elena была одним из основных участников проекта Apache Xerces2 и работала над Xerces2 XML Schema и реализациями DOM Level 3, а также над анализом работы и улучшением производительности синтаксического анализатора. Елена также представляла IBM в W3C DOM Working Group и участвовала в разработке спецификаций DOM Level 3. |
Выскажите мнение об этой странице
|  |