« Управление проектами вместе с JIRA. Часть 1 | JSTL: Шаблоны для разработки веб-приложений в java. Часть 3 » |
JSTL: Шаблоны для разработки веб-приложений в java. Часть 2
В прошлый раз я рассказал о тегах основного назначения, сегодня самое время перейти к средствам позволяющим работать с xml. Прежде всего, мы должны в заголовке jsp страницы подключить следующую библиотеку тегов:<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<?xml version="1.0" encoding="utf-8"?>
<bookshelf>
<book id="12">
<title>Книга про зайцев</title>
<description><![CDATA[Книга �рассказывает про суровую
судьбу молодой семьи зайцев, живущих в самый разгар ...]]></description>
<price>99.95</price>
<authors>
<author main="true">Тапкин Василий Васильевич</author>
<author>Пупкина Ленка Ленковна</author>
</authors>
</book>
<book id="13">
<title>Слоны-людоеды</title>
<description><![CDATA[Книга создана по материалам расследования серии
жестоких убийств в местном зоопарке]]></description>
<price>29.95</price>
<authors>
<author main="true">Слоноглазов Глеб Гамбитович</author>
<author>Слоноухова Виктория Мракобесовна</author>
</authors>
</book>
</bookshelf>
<x:parse var="bookshelf">
<?xml version="1.0" encoding="utf-8"?>
<bookshelf>
<book id="12">
<title>Книга про зайцев</title>
<description><![CDATA[Книга �рассказывает про суровую судьбу
молодой семьи зайцев, живущих в самый разгар ...]]></description>
<price>99.95</price>
<authors>
<author main="true">Тапкин Василий Васильевич</author>
<author>Пупкина Ленка Ленковна</author>
</authors>
</book>
<book id="13">
<title>Слоны-людоеды</title>
<description><![CDATA[Книга создана по материалам расследования
серии жестоких убийств в местном зоопарке]]></description>
<price>29.95</price>
<authors>
<author main="true">Слоноглазов Глеб Гамбитович</author>
<author>Слоноухова Виктория Мракобесовна</author>
</authors>
</book>
</bookshelf>
</x:parse>
<x:parse var="bookshelf2" xml="${helloMachine.bookshelfAsString}" />
public String getBookshelfAsString() {
try {
BufferedReader brin = new BufferedReader(
new InputStreamReader(getClass().getResourceAsStream("/testi/templates/book.xml")));
StringBuffer buf = new StringBuffer();
String line;
while ((line = brin.readLine()) != null)
buf.append(line);
return buf.toString();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
Где-искать/Чего-искатьГде искать – это java-переменная ссылающаяся на xml-дерево. Имя ее может быть как просто bookshelf (см. прошлый пример), так и содержать имя контекста, например: pageScope:bookshelf.
Вот примеры, отбирающие разные части xml-документа (пусть вас не смущает то, что у меня и имя переменной в которой хранится xml-документ и имя первого тега совпадают – это ничего не значит):
<x:parse var="bookshelf">
<c:import url="book.xml" charEncoding="utf-8" />
</x:parse>
all book content:<x:out select="$bookshelf/bookshelf/book[1]" escapeXml="false"/>
id:<x:out select="$bookshelf/bookshelf/book[1]/@id" />
title:<x:out select="$bookshelf/bookshelf/book[1]/title" />
qty authors:<x:out select="count($bookshelf/bookshelf/book[1]/authors/author)" />
Теперь проблема: если я к xml-документу добавлю пространства имен, например, так:
<bookshelf xmlns="http://books.com/buki">
all book content:<x:out select="$bookshelf/*[name()='bookshelf']/*[name()='book'][1]" escapeXml="false"/>
id:<x:out select="$bookshelf/*[name()='bookshelf']/*[name()='book'][1]/@id" />
title:<x:out select="$bookshelf/*[name()='bookshelf']/*[name()='book'][1]/*[name()='title']" />
qty authors:<x:out select="count($bookshelf/*[name()='bookshelf']/*[name()='book'][1]/*[name()='authors']/*[name()='author'])" />
При записи сложных xpath-выражений можно ссылаться на объявленные в jstl переменные, например, далее я хочу найти в списке книг только ту, номер которой был передан как входной параметр скрипту:
book title by bid: <x:out select="$bookshelf/bookshelf/book[@id = $param:bid]/title" />
<x:set var="bookTitle" select="$bookshelf/bookshelf/book[1]/title" />
book title = <x:out select="$bookTitle/." />
<x:forEach select="$bookshelf/bookshelf/book" var="book">
<h1>
<x:out select="$book/title" />
</h1>
<ul>
<x:forEach select="$book/authors/author" var="author">
<li>
<x:out select="$author" />
</li>
</x:forEach>
</ul>
</x:forEach>
<x:forEach select="$bookshelf/bookshelf/book" var="book">
<h1>
<x:out select="$book/title" />
</h1>
<x:if select="count($book/authors/author) >= 2">
Два или более писателя сотворили сей опус
</x:if>
</x:forEach>
<x:if select="$bookshelf/bookshelf/book[@id = $param:bid]" var="xxx" />
<x:forEach select="$bookshelf/bookshelf/book" var="book">
<h1>
<x:out select="$book/title" />
</h1>
<x:choose>
<x:when select="count($book/authors/author) = 0">
У книги нет авторов, вообще.
</x:when>
<x:when select="count($book/authors/author) = 1">
Только один автор
</x:when>
<x:otherwise>
Количество авторов неизвестно, но их точно более чем один
</x:otherwise>
</x:choose>
</x:forEach>
transbook.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" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:for-each select="bookshelf/book">
<h1>
<xsl:value-of select="title" disable-output-escaping="yes" />
</h1>
<ul>
<xsl:for-each select="authors/author">
<li>
<xsl:value-of select="." disable-output-escaping="yes" />
</li>
</xsl:for-each>
</ul>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
У тега transform есть два обязательных атрибута: xml – содержит входные данные для трансформации, и атрибут xslt, задающий правила по которым трансформация будет выполнена. Вот только … неожиданный момент, что оба входные параметр xslt – это не xml-документы созданный с помощью x:parse, а строки текста с их значениями.
<c:set var="bookshelf">
<c:import url="book.xml" charEncoding="utf-8" />
</c:set>
<c:set var="transbook">
<c:import url="transbook.xsl" charEncoding="utf-8" />
</c:set>
<x:transform xml="${bookshelf}" xslt="${transbook}" />
<c:set var="transbook_0">
<c:import url="transbook_0.xsl" charEncoding="utf-8" />
</c:set>
<c:set var="transbook_1">
<c:import url="transbook_1.xsl" charEncoding="utf-8" />
</c:set>
<c:set var="transbook_2">
<c:import url="transbook_2.xsl" charEncoding="utf-8" />
</c:set>
<x:transform xslt="${transbook_2}">
<x:transform xslt="${transbook_1}">
<x:transform xslt="${transbook_0}" xml="${bookshelf}"/>
</x:transform>
</x:transform>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="fio" />
<xsl:template match="/">
<h1>
<xsl:value-of select="$fio" disable-output-escaping="yes" />
</h1>
<xsl:for-each select="bookshelf/book">
<h1>
<xsl:value-of select="title" disable-output-escaping="yes" />
</h1>
<ul>
<xsl:for-each select="authors/author">
<li>
<xsl:value-of select="." disable-output-escaping="yes" />
</li>
</xsl:for-each>
</ul>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
<x:transform xml="${bookshelf}" xslt="${transbook}" >
<x:param name="fio" value="Petyano" />
</x:transform>
« Управление проектами вместе с JIRA. Часть 1 | JSTL: Шаблоны для разработки веб-приложений в java. Часть 3 » |