Почему при использовании скриптов, приведенных в курсе Основы XML лекция Лекция 8: Отображение XML-документов с использованием связывания данных не происходит связывания XLM документа с HTML? Отображаются пустые поля. Браузер IE11 |
Отображение XML-документов с использованием XSL-таблиц стилей
Отображение переменного числа элементов
В примере, рассмотренном в предыдущем разделе (см. Листинг 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/1999/XSL/Transform" version="1.0"> <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.
Чтобы отобразить все отвечающие образцу элементы, следует использовать XSL-элемент for-each, который вызывает повторный вывод для каждого из содержащихся в XML-файле элементов. XSL-таблица стилей, представленная в Листинге 10.3, демонстрирует данную методику. Эта таблица стилей связана с XML-документом, содержащимся в Листинге 10.4.
<?xml version="1.0"?> <!-- File name: XslDemo02.xsl --> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <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
<?xml version="1.0"?> <!-- File name: XslDemo.xml --> <?xml-stylesheet type="text/xsl" href="XslDemo02.xsl"?> <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> <BOOK> <TITLE>The Awakening</TITLE> <AUTHOR> <FIRSTNAME>Kate</FIRSTNAME> <LASTNAME>Chopin</LASTNAME> </AUTHOR> <BINDING>mass market paperback</BINDING> <PAGES>195</PAGES> <PRICE>$4.95</PRICE> </BOOK> <BOOK> <TITLE>Billy Budd</TITLE> <AUTHOR> <FIRSTNAME>Herman</FIRSTNAME> <LASTNAME>Melville</LASTNAME> </AUTHOR> <BINDING>mass market paperback</BINDING> <PAGES>195</PAGES> <PRICE>$4.49</PRICE> </BOOK> <BOOK> <TITLE>A Connecticut Yankee in King Arthur's Court</TITLE> <AUTHOR> <FIRSTNAME>Mark</FIRSTNAME> <LASTNAME>Twain</LASTNAME> </AUTHOR> <BINDING>mass market paperback</BINDING> <PAGES>385</PAGES> <PRICE>$5.49</PRICE> </BOOK> <BOOK> <TITLE>Joan of Arc</TITLE> <AUTHOR> <FIRSTNAME>Mark</FIRSTNAME> <LASTNAME>Twain</LASTNAME> </AUTHOR> <BINDING>trade paperback</BINDING> <PAGES>465</PAGES> <PRICE>$6.95</PRICE> </BOOK> <BOOK> <TITLE>Leaves of Grass</TITLE> <AUTHOR> <FIRSTNAME>Walt</FIRSTNAME> <LASTNAME>Whitman</LASTNAME> </AUTHOR> <BINDING>hardcover</BINDING> <PAGES>462</PAGES> <PRICE>$7.75</PRICE> </BOOK> <BOOK> <TITLE>The Legend of Sleepy Hollow</TITLE> <AUTHOR> <FIRSTNAME>Washington</FIRSTNAME> <LASTNAME>Irving</LASTNAME> </AUTHOR> <BINDING>mass market paperback</BINDING> <PAGES>98</PAGES> <PRICE>$2.95</PRICE> </BOOK> <BOOK> <TITLE>The Marble Faun</TITLE> <AUTHOR> <FIRSTNAME>Nathaniel</FIRSTNAME> <LASTNAME>Hawthorne</LASTNAME> </AUTHOR> <BINDING>trade paperback</BINDING> <PAGES>473</PAGES> <PRICE>$10.95</PRICE> </BOOK> <BOOK> <TITLE>Moby-Dick</TITLE> <AUTHOR> <FIRSTNAME>Herman</FIRSTNAME> <LASTNAME>Melville</LASTNAME> </AUTHOR> <BINDING>hardcover</BINDING> <PAGES>724</PAGES> <PRICE>$9.95</PRICE> </BOOK> <BOOK> <TITLE>Passing</TITLE> <AUTHOR> <FIRSTNAME>Nella</FIRSTNAME> <LASTNAME>Larsen</LASTNAME> </AUTHOR> <BINDING>trade paperback</BINDING> <PAGES>165</PAGES> <PRICE>$5.95</PRICE> </BOOK> <BOOK> <TITLE>The Portrait of a Lady</TITLE> <AUTHOR> <FIRSTNAME>Henry</FIRSTNAME> <LASTNAME>James</LASTNAME> </AUTHOR> <BINDING>mass market paperback</BINDING> <PAGES>256</PAGES> <PRICE>$4.95</PRICE> </BOOK> <BOOK> <TITLE>Roughing It</TITLE> <AUTHOR> <FIRSTNAME>Mark</FIRSTNAME> <LASTNAME>Twain</LASTNAME> </AUTHOR> <BINDING>mass market paperback</BINDING> <PAGES>324</PAGES> <PRICE>$5.25</PRICE> </BOOK> <BOOK> <TITLE>The Scarlet Letter</TITLE> <AUTHOR> <FIRSTNAME>Nathaniel</FIRSTNAME> <LASTNAME>Hawthorne</LASTNAME> </AUTHOR> <BINDING>trade paperback</BINDING> <PAGES>253</PAGES> <PRICE>$4.25</PRICE> </BOOK> <BOOK> <TITLE>The Turn of the Screw</TITLE> <AUTHOR> <FIRSTNAME>Henry</FIRSTNAME> <LASTNAME>James</LASTNAME> </AUTHOR> <BINDING>trade paperback</BINDING> <PAGES>384</PAGES> <PRICE>$3.35</PRICE> </BOOK> </INVENTORY>Листинг 10.4. XslDemo.xml
Шаблон в таблице стилей из Листинга 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 элемента for-each, работает точно так же, как образец, присваиваемый атрибуту select элемента value-of ;
- внутри элемента for-each задает текущий элемент, устанавливаемый атрибутом select элемента for-each ( /INVENTORY/BOOK в нашем примере указывает на элемент BOOK внутри элемента INVENTORY, входящего в корневой элемент документа) следующим образом:
<xsl:stylesheet xmlns:xsl=http://www.w3.org/1999/XSL/Transform version="1.0"> <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 ; чтобы отобразить остальные, необходимо осуществить прокрутку вниз.)