Основы XML

       

Отображение переменного числа элементов


В примере, рассмотренном в предыдущем разделе (см. Листинг 10.2), XML-документ содержал только один элемент BOOK. В случае, если документ содержит несколько элементов BOOK, методика, с которой вы познакомились в предыдущем разделе, способна отобразить только один из элементов. Возьмем, для примера, XML-документ, содержащий следующий элемент Документ:

<INVENTORY> <BOOK> <TITLE>The Adventures of Huckleberry Finn</TITLE> <AUTHOR> <FIRSTNAME>Mark</FIRSTNAME> <LASTNAME>Twain</LASTNAME> </AUTHOR> <BINDING>mass market paperback</BINDING> <PAGES>298</PAGES> <PRICE>$5.49</PRICE> </BOOK> <BOOK> <TITLE>The Adventures of Tom Sawyer</TITLE> <AUTHOR> <FIRSTNAME>Mark</FIRSTNAME> <LASTNAME>Twain</LASTNAME> </AUTHOR> <BINDING>mass market paperback</BINDING> <PAGES>205</PAGES> <PRICE>$4.75</PRICE> </BOOK> <BOOK> <TITLE>The Ambassadors</TITLE> <AUTHOR> <FIRSTNAME>Henry</FIRSTNAME> <LASTNAME>James</LASTNAME> </AUTHOR> <BINDING>mass market paperback</BINDING> <PAGES>305</PAGES> <PRICE>$5.95</PRICE> </BOOK> </INVENTORY>

Предположим, что таблица стилей, используемая для отображения этого документа, содержит следующий шаблон:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> <xsl:template match="/"> <H2>Book Description</H2> <SPAN STYLE="font-style:italic">Author: </SPAN> <xsl:value-of select="INVENTORY/BOOK/AUTHOR"/><BR/> <SPAN STYLE="font-style:italic">Title: </SPAN> <xsl:value-of select="INVENTORY/BOOK/TITLE"/><BR/> <SPAN STYLE="font-style:italic">Price: </SPAN> <xsl:value-of select="INVENTORY/BOOK/PRICE"/><BR/> <SPAN STYLE="font-style:italic">Binding type: </SPAN> <xsl:value-of select="INVENTORY/BOOK/BINDING"/><BR/> <SPAN STYLE="font-style:italic">Number of pages: </SPAN> <xsl:value-of select="INVENTORY/BOOK/PAGES"/> </xsl:template> </xsl:stylesheet>


Этот шаблон использует методику, описанную в предыдущем разделе. Обратите внимание, что образец присваиваемых каждому атрибуту select начинается с указания элемента Документ, в данном случае INVENTORY (например, "INVENTORY/BOOK/AUTHOR").

Каждый образец, однако, соответствует трем различным элементам. Например, "INVENTORY/BOOK/AUTHOR" соответствует элементу AUTHOR для всех трех элементов BOOK. В подобной ситуации браузер использует только первый из соответствующих элементов. Таким образом, таблица стилей отобразит содержимое только первого элемента BOOK, как показано на рисунке 10.3.


Рис. 10.3. 

Чтобы отобразить все отвечающие образцу элементы, следует использовать XSL-элемент for-each, который вызывает повторный вывод для каждого из содержащихся в XML-файле элементов. XSL-таблица стилей, представленная в Листинге 10.3, демонстрирует данную методику. Эта таблица стилей связана с XML-документом, содержащимся в Листинге 10.4.

xml version="1.0"?>

<!-- Имя файла: XslDemo02.xsl -->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> <xsl:template match="/"> <H2>Book Inventory</H2> <xsl:for-each select="INVENTORY/BOOK"> <SPAN STYLE="font-style:italic">Title: </SPAN> <xsl:value-of select="TITLE"/><BR /> <SPAN STYLE="font-style:italic">Author: </SPAN> <xsl:value-of select="AUTHOR"/><BR /> <SPAN STYLE="font-style:italic">Binding type: </SPAN> <xsl:value-of select="BINDING"/><BR /> <SPAN STYLE="font-style:italic">Number of pages: </SPAN> <xsl:value-of select="PAGES"/><BR /> <SPAN STYLE="font-style:italic">Price: </SPAN> <xsl:value-of select="PRICE"/><P /> </xsl:for-each> </xsl:template> </xsl:stylesheet>

Листинг 10.3. XslDemo02.xsl (html, txt)



Листинг 10.4. XslDemo.xml (html, txt)

Шаблон в таблице стилей из Листинга 10.3 содержит следующий элемент for-each:

<xsl:for-each select="INVENTORY/BOOK"> <SPAN STYLE="font-style:italic">Title: </SPAN> <xsl:value-of select="TITLE"/><BR /> <SPAN STYLE="font-style:italic">Author: </SPAN> <xsl:value-of select="AUTHOR"/><BR /> <SPAN STYLE="font-style:italic">Binding type: </SPAN> <xsl:value-of select="BINDING"/><BR /> <SPAN STYLE="font-style:italic">Number of pages: </SPAN> <xsl:value-of select="PAGES"/><BR /> <SPAN STYLE="font-style:italic">Price: </SPAN> <xsl:value-of select="PRICE"/><P /> </xsl:for-each>

Элемент for-each выполняет две основные задачи:

  • осуществляет вывод блока элементов, содержащихся внутри элемента for-each, повторяя его для каждого XML-элемента в документе, отвечающего образцу, присвоенному атрибуту select элемента for-each. В данном примере цикл выполняется по одному разу для каждого элемента BOOK, найденного в элементе Документ с именем INVENTORY. Образец, присваиваемый атрибуту select, работает точно так же, как образец, присваиваемый атрибуту select элемента value-of;
  • внутри элемента for-each задает текущий элемент, устанавливаемый атрибутом select элемента for-each (/INVENTORY/BOOK в нашем примере указывает на элемент BOOK внутри элемента INVENTORY, входящего в корневой элемент документа) следующим образом:

    <xsl:stylesheet xmlns:xsl=http://www.w3.org/TR/WD-xsl> <xsl:template match="/"> <!-- Здесь текущим является корневой "элемент" документа, "/". --> <xsl:for-each select="INVENTORY/BOOK"> <!-- Здесь текущим является элемент /INVENTORY/BOOK. --> </xsl:for-each> </xsl:template> </xsl:stylesheet>

    Аналогично, внутри элемента for-each каждый дочерний элемент может быть выбран путем задания образца, содержащего только имя элемента, например:



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

    В результате выводятся данные из всех элементов BOOK, найденных в документе, независимо от того, сколько этих элементов содержит документ. На рисунке 10.4 показано как выглядит результат в Internet Explorer 5. (В окне отображены только первые три элемента BOOK; чтобы отобразить остальные, необходимо осуществить прокрутку вниз.)


    Рис. 10.4. 

    Содержание раздела