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 enumParserEnum {

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);

}

}

XSL

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

Существует два стандарта стилевых таблиц, опубликованных W3C. Это CSS (Cascading Stylesheet) и XSL (XML Stylesheet Language).

CSS изначально разрабатывался для HTML и представляет из себя набор инструкций, которые указывают браузеру, какой шрифт, размер, цвет использовать для отображения элементов HTML-документа.

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

Вообще XSL можно разделить на три части: XSLT (XSL Transformation), XPath и XSLFO (XSL Formatting Objects).

XSL Processor необходим для преобразования XML-документа согласно инструкциям, находящимся в файле таблицы стилей.

XSLT

Этот язык для описания преобразований XML-документа применяется не только для приведения XML-документов к некоторому “читаемому” виду, но и для изменения структуры XML-документа.

К примеру, XSLT можно использовать для:

· удаления существующих или добавления новых элементов в XML-документ;

· создания нового XML-документа на основании заданного;

· извлечения информации из XML-документа с разной степенью детализации;

· преобразования XML-документа в документ HTML или документ другого типа.

Пусть требуется построить новый XML-файл на основе файла
students.xml, у которого будет удален атрибут login. Элементы country, city, street станут атрибутами элемента address и элемент telephone станет дочерним элементом элемента address. Следует воспользоваться XSLT для решения данной задачи. В следующем коде приведено содержимое файла таблицы стилей students.xsl, решающее поставленную задачу.

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

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" />

<xsl:template match="/">

<students>

<xsl:apply-templates />

</students>

</xsl:template>

<xsl:template match="student">

<xsl:element name="student">

<xsl:attribute name="faculty">

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

</xsl:attribute>

<name><xsl:value-of select="name"/></name>

<xsl:element name="address">

<xsl:attribute name="country">

<xsl:value-of select="address/country"/>

</xsl:attribute>

<xsl:attribute name="city">

<xsl:value-of select="address/city"/>

</xsl:attribute>

<xsl:attribute name="street">

<xsl:value-of select="address/street"/>

</xsl:attribute>

<xsl:element name="telephone">

<xsl:attribute name="number">

<xsl:value-of select="telephone"/>

</xsl:attribute>

</xsl:element>

</xsl:element>

</xsl:element>

</xsl:template>

</xsl:stylesheet>

Преобразование XSL лучше сделать более коротким, используя ATV (attribute template value), т.е «{}»

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

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" />

<xsl:template match="/">

<students>

<xsl:apply-templates />

</students>

</xsl:template>

<xsl:template match="student">

<student faculty=”{@faculty}">

<name><xsl:value-of select="name"/></name>

<address country=”{address/country}"

city=”{address/city}”

street=”{address/street}”>

<telephone number="{telephone}"/>

</address>

</student>

</xsl:template>

</xsl:stylesheet>

Для трансформации одного документа в другой можно использовать, например, следующий код.

/* пример # 14 : трансформация XML : SimpleTransform.java */

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerException;

import javax.xml.transform.TransformerFactory;

import javax.xml.transform.stream.StreamResult;

import javax.xml.transform.stream.StreamSource;

 

public class SimpleTransform {

public static void main(String[] args) {

try {

TransformerFactory tf =

TransformerFactory.newInstance();

 

//установка используемого XSL-преобразования

Transformer transformer =

tf.newTransformer(new StreamSource("students.xsl"));

 

//установка исходного XML-документа и конечного XML-файла

transformer.transform(

new StreamSource("students.xml"),

new StreamResult("newstudents.xml"));

 

System.out.print("complete");

} catch(TransformerException e) {

e.printStackTrace();

}

}

}

В результате получится XML-документ newstudents.xml следующего вида:

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

<students>

<student faculty="mmf">

<name>Mitar Alex</name>

<address country="Belarus" city="Minsk"

street="Kalinovsky 45">

<telephone number="3462356"/>

</address>

</student>

<student faculty="mmf">

<name>Pashkun Alex</name>

<address country="Belarus" city="Brest"

street="Knorina 56">

<telephone number="4582356"/>

</address>

</student>

</students>

Элементы таблицы стилей

Таблица стилей представляет собой well-formed XML-документ. Эта таблица описывает изначальный документ, конечный документ и то, как трансформировать один документ в другой.

Какие же элементы используются в данном листинге?

<xsl:output method="xml" indent="yes"/>

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

<xsl:template match="student">

<lastname>

<xsl:apply-templates/>

</lastname>

</xsl:template>

Инструкция <xsl:template...> задает шаблон преобразования. Набор шаблонов преобразования составляет основную часть таблицы стилей. В предыдущем примере приводится шаблон, который преобразует элемент student в элемент lastname.

Шаблон состоит из двух частей:

1) параметр match, который задает элемент или множество элементов в исходном дереве, где будет применяться данный шаблон;

2) содержимое шаблона, которое будет вставлено в конечный документ.

Нужно отметить, что содержимое параметра math может быть довольно сложным. В предыдущем примере просто ограничились именем элемента. Но, к примеру, следующее содержимое параметра mathуказывает на то, что шаблон должен применяться к элементу url, содержащему атрибут protocolсо значением mailto:

<xsl:template match=”url[@protocol=’mailto’]”>

Кроме этого, существует набор функций, которые также могут использоваться при объявлении шаблона:

<xsl:template match=”chapter[position()=2]”>

Данный шаблон будет применен ко второму по счету элементу chapterисходного документа.

Инструкция <xsl:apply-templates/> сообщает XSL-процессору о том, что нужно перейти к просмотру дочерних элементов. Эта запись означает в расширенном виде:

<xsl:apply-templates select=”child::node()” />

XSL-процессор работает по следующему алгоритму. После загрузки исходного XML-документа и таблицы стилей процессор просматривает весь документ от корня до листьев. На каждом шагу процессор пытается применить к данному элементу некоторый шаблон преобразования; если в таблице стилей для текущего просматриваемого элемента есть шаблон, процессор вставляет в результирующий документ содержимое этого шаблона. Когда процессор встречает инструкцию <xsl:apply-templates/>, он переходит к дочерним элементам текущего узла и повторяет процесс, т.е. пытается для каждого дочернего элемента найти соответствие в таблице стилей.

Задания к главе 16

Вариант А

Создать файл XML и соответствующее ему DTD-определение. Задать схему XSD. Определить класс Java, соответствующий данному описанию. Создать Java-приложение для инициализации массива объектов информацией из XML-файла. Произвести проверку XML-документа с привлечением DTD и XSD. Определить метод, производящий преобразование данного XML-документа в документ, указанный в задании.

Оранжерея.

Растения, содержащиеся в оранжерее, имеют следующие характеристики:

· Name – название растения.

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

· Origin – место происхождения растения.

· Visual рarameters (должно быть несколько) – внешние параметры: цвет стебля, цвет листьев, средний размер растения.

· Growing tips (должно быть несколько) – предпочитаемые условия произрастания: температура (в градусах), освещение (светолюбиво либо нет), полив (мл в неделю).

· Multiplying – размножение: листьями, черенками либо семенами.

Корневой элемент назвать Flower.

Создать XML файл, отображающий заданную тему, привести примеры 4-5 растений. С помощью XSL преобразовать данный файл в формат HTML, где отобразить растения по предпочитаемой тем­пературе (по возрастанию).

Алмазный фонд.

Драгоценные и полудрагоценные камни, содержащиеся в павильоне, имеют следующие характеристики:

· Name – название камня.

· Preciousness – может быть драгоценным либо полудрагоценным.

· Origin – место добывания.

· Visual parameters (должно быть несколько) – могут быть: цвет (зеленый, красный, желтый и т.д.), прозрачность (измеряется в процентах
0-100%), способы огранки (количество граней 4-15).

· Value – вес камня (измеряется в каратах).

Корневой элемент назвать Gem.

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