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 , где корневым элементом будет место происхождения.