StAX анализатор XML для Java

StAX (Streaming API for XML), который еще называют pull-парсером, включен в JDK, начиная с версии Java SE 6. Он похож на SAX отсутствием объектной модели в памяти и последовательным продвижением по XML, но в StAX не требуется реализация интерфейсов, и приложение само командует StAX-парсеру перейти к следующему элементу XML. Кроме того, в отличие от SAX, данный парсер предлагает API для создания XML-документа.

Основными классами StAX являются XMLInputFactory, XMLStreamReader и XMLOutputFactory, XMLStreamWriter, которые соответственно используются для чтения и создания XML-документа. Для чтения XML надо получить ссылку на XMLStreamReader:

StringReader stringReader = new StringReader(xmlString);

XMLInputFactory inputFactory=XMLInputFactory.newInstance();

XMLStreamReader reader = inputFactory

.createXMLStreamReader(stringReader);

после чего XMLStreamReader можно применять аналогично интерфейсу Iterator, используя методы hasNext() и next():

boolean hasNext() – показывает, есть ли еще элементы;

int next() – переходит к следующей вершине XML, возвращая ее тип.

Возможные типы вершин:

XMLStreamConstants.START_DOCUMENT

XMLStreamConstants.END_DOCUMENT

XMLStreamConstants.START_ELEMENT

XMLStreamConstants.END_ELEMENT

XMLStreamConstants.CHARACTERS

XMLStreamConstants.ATTRIBUTE

XMLStreamConstants.CDATA

XMLStreamConstants.NAMESPACE

XMLStreamConstants.COMMENT

XMLStreamConstants.ENTITY_DECLARATION

Далее данные извлекаются применением методов:

String getLocalName() – возвращает название тега;

String getAttributeValue(NAMESPACE_URI, ATTRIBUTE_NAME) – возвращает значение атрибута;

String getText() – возвращает текст тега.

Пусть дан XML-документ с описанием медиатехники.

<?xml version="1.0" encoding="UTF-8"?>

<products xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation=" products.xsd">

<category name="Audio And Video">

<subcategory name="Audio">

<product>

<producer>Samsung</producer>

<model>NV678</model>

<year>12-12-2006</year>

<color>White</color>

<notAvailable />

</product>

</subcategory>

<subcategory name="Video">

<product>

<producer>Samsung</producer>

<model>VH500</model>

<year>12-12-2004</year>

<color>Black</color>

<cost>200</cost>

</product>

<product>

<producer>Samsung</producer>

<model>VH500</model>

<year>12-12-2004</year>

<color>White</color>

<notAvailable />

</product>

</subcategory>

</category>

<category name="Computers">

<subcategory name="Pocket">

<product>

<producer>HP</producer>

<model>rx371</model>

<year>31-01-2006</year>

<color>Black</color>

<notAvailable />

</product>

</subcategory>

</category>

</products>

Организация процесса разбора документа XML с помощью StAX приведена в следующем примере:

/* пример # 12 : реализация разбора XM-документа : StAXProductParser.java : ProductParser.java: ParserEnum.java */

package chapt16;

public enum ParserEnum {

PRODUCTS, CATEGORY, SUBCATEGORY, PRODUCT, PRODUCER, MODEL, YEAR, COLOR, NOTAVAILABLE, COST, NAME

}

package chapt16;

import java.io.InputStream;

public abstract class ProductParser {

public abstract void parse(InputStream input);

public void writeTitle() {

System.out.println("Products:");

}

public void writeCategoryStart(String name) {

System.out.println("Category: " + name.trim());

}

public void writeCategoryEnd() {

System.out.println();

}

public void writeSubcategoryStart(String name) {

System.out.println("Subcategory: " + name.trim());

}

public void writeSubcategoryEnd() {

System.out.println();

}

public void writeProductStart() {

System.out.println(" Product Start ");

}

public void writeProductEnd() {

System.out.println(" Product End ");

}

public void writeProductFeatureStart(String name) {

switch (ParserEnum.valueOf(name.toUpperCase())) {

case PRODUCER:

System.out.print("Provider: ");

break;

case MODEL:

System.out.print("Model: ");

break;

case YEAR:

System.out.print("Date of issue: ");

break;

case COLOR:

System.out.print("Color: ");

break;

case NOTAVAILABLE:

System.out.print("Not available");

break;

case COST:

System.out.print("Cost: ");

break;

}

}

public void writeProductFeatureEnd() {

System.out.println();

}

public void writeText(String text) {

System.out.print(text.trim());

}

}

package chapt16;

import javax.xml.stream.XMLInputFactory;

import javax.xml.stream.XMLStreamConstants;

import javax.xml.stream.XMLStreamException;

import javax.xml.stream.XMLStreamReader;

import java.io.InputStream;

public class StAXProductParser extends ProductParser {

// реализация абстрактного метода из суперкласса для разбора потока

public void parse(InputStream input) {

XMLInputFactory inputFactory =

XMLInputFactory.newInstance();

try {

XMLStreamReader reader =

inputFactory.createXMLStreamReader(input);

process(reader);

} catch (XMLStreamException e) {

e.printStackTrace();

}

}

// метод, управляющий разбором потока

public void process(XMLStreamReader reader)

throws XMLStreamException {

String name;

while (reader.hasNext()) {

// определение типа "прочтённого" элемента (тега)

int type = reader.next();

switch (type) {

case XMLStreamConstants.START_ELEMENT:

name = reader.getLocalName();

switch (ParserEnum.valueOf(name.toUpperCase())) {

case PRODUCTS:

writeTitle();

break;

case CATEGORY:

writeCategoryStart(reader.getAttributeValue(null,

ParserEnum.NAME.name().toLowerCase()));

break;

case SUBCATEGORY:

writeSubcategoryStart(reader.getAttributeValue(null,

ParserEnum.NAME.name().toLowerCase()));

break;

case PRODUCT:

writeProductStart();

break;

default:

writeProductFeatureStart(name);

break;

}

break;

case XMLStreamConstants.END_ELEMENT:

name = reader.getLocalName();

switch (ParserEnum.valueOf(name.toUpperCase())) {

case CATEGORY:

writeCategoryEnd();

break;

case SUBCATEGORY:

writeSubcategoryEnd();

break;

case PRODUCT:

writeProductEnd();

break;

default:

writeProductFeatureEnd();

break;

}

break;

case XMLStreamConstants.CHARACTERS:

writeText(reader.getText());

break;

default:

break;

}

}

}

}

Для запуска приложения разбора документа с помощью StAX ниже приведен достаточно простой код:

/* пример # 13 : запуск приложения : StreamOutputExample.java*/

package chapt16;

import java.io.FileInputStream;

import java.io.InputStream;

public class StreamOutputExample {

public static void main(String[] args) throws Exception {

ProductParser parser = new StAXProductParser();

// создание входного потока данных из xml-файла

InputStream input =

new FileInputStream("chapt16\\mediatech.xml");

// разбор файла с выводом результата на консоль

parser.parse(input);

}

}

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100