Главная » XSLT » Создание фреймов

0

Задача

Требуется сгенерировать HTML-разметку, в которой содержимое организо­вано с помощью фреймов.

Решение

Как и в рецепте 10.2, воспользуемся режимами для выполнения несколь­ких проходов по XML-документу. Сначала создается контейнер фреймов, со­держащий тег <FRAMESET>. Мы создадим всего два фрейма; меньший фрейм слева будет содержать имена продавцов в виде гиперссылок, загружающих со­держимое в правый фрейм. Правый – основной – фрейм будет содержать дан­ные о продажах для выбранного пользователем продавца. В примере генерируется также документ, отображаемый в основном фрейме при первой загрузке страницы.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html"/> <xsl:param name="URL"/>

<xsl:template match="/">

<xsl:apply-templates select="*" mode="frameset"/> <xsl:apply-templates select="*" mode="salespeople_frame"/>

<xsl:apply-templates select="*" mode="sales_frames"/>

</xsl:template>

<!– = = = = = = = = = = = = = = = = = — >

<!– Создать контейнер для фреймов (mode ="frameset") –> <!– = = = = = = = = = = = = = = = = = — >

<xsl:template match="salesBySalesperson" mode="frameset"> <!– Нестандартный элемент saxon xsl:document! –> <xsl:document href="index.html"> <html> <head>

<title>Данные о продавцах</title> </head>

<frameset rows="100%" cols="25%, 75%" border="0">

<frame name="salespeople" src="salespeople_frame.html" noresize=""/> <frame name="mainFrame" src="default_sales.html" noresize=""/> </frameset> <body bgcolor="#FFFFFF" text="#000000"> </body> </html> </xsl:document>

</xsl:template>

<!– = = = = = = = = = = = = = = = = = — >

<!– Создать salespeople_frame.html (mode = "salespeople_frame") –> <!– = = = = = = = = = = = = = = = = = — >

<xsl:template match="salesBySalesperson" mode="salespeople_frame"> <!– Нестандартный элемент saxon xsl:document! –> <xsl:document href="salespeople_frame.html"> <html> <head>

<title>Salespeople</title> </head>

<body bgcolor="#FFFFFF" text="#000000"> <table> <tbody>

<xsl:apply-templates mode="index"/> </tbody> </table> </body> </html> </xsl:document> </xsl:template>

<xsl:template match="salesperson" mode="index">

<tr> <td>

<a href="{concat(@name,’.html’)}"

target="mainFrame"><xsl:value-of select="@name"/></a>

</td> </tr>

</xsl:template>

<!– = = = = = = = = = = = = = = = = = — >

<!–                                              Создать gname.html (mode = "content")     –>

<!– = = = = = = = = = = = = = = = = = — >

<xsl:template match="salesperson" mode="sales_frames">

<xsl:document href="default_sales.html"> <html> <head>

<title^o yмoлчaнию</title> </head>

<body bgcolor="#FFFFFF" text="#000000"> <h1><center>Пpoдaжи для одного пpoдaвцa</center></h1> <br/>

Щелкните по имени пpoдaвцa в левом (^ейме, чтобы зaгpyзить данные о пpoдaжax для него.

</body> </html> </xsl:document>

<xsl:document href="{concat(@name,’.html’)}"> <html> <head>

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

<body bgcolor="#FFFFFF" text="#000000"> <h1><center>Пpoдaжи для одного пpoдaвцa</center></h1> <h2><xsl:value-of select="@name"/></h2> <table border="1" cellpadding="3"> <tbody > <tr>

<th>Пoзиция</th> <th>Пpoдaжи (в US $)</th> </tr>

<xsl:apply-templates mode="content"/> </tbody> </table> </body> </html> </xsl:document>

</xsl:template>

<xsl:template match="product" mode="content"> <tr>

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

<td align="right"><xsl:value-of select="@totalSales"/></td> </tr>

</xsl:template>

</xsl:stylesheet>

Обсуждение

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

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

<html>

<head>

<title>Frameset</title> </head>

frameset rows="100%" cols="25%, 75%" border="0">

frame name="leftFrame" src="left.xml" noresize=""> frame name="mainFrame" src="main.xml" noresize=""> </frameset>

<body bgcolor="#FFFFFF" text="#0 0 0 0 0 0"></body>

</html>

Загружать в разные фреймы различные XML-документы приходится потому, что в файле может быть не более одной команды xml-stylesheet. Однако зна­чимое содержимое можно по-прежнему хранить в одной таблице стилей, восполь­зовавшись командой xinclude (http://www.w3.org/TR/xinclude/) и XSLT-шабло- ном для ее обработки:

Файл left.xml выглядит так:

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

<?xml-stylesheet type="application/xml" href="left.xsl"?> <xi:include href="salesBySalesperson.xml"

xmlns:xi="http://www.w3.org/2001/XInclude"/>

а файл main.xml – так:

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

<?xml-stylesheet type="application/xml" href="main.xsl"?> <xi:include href="salesBySalesperson.xml"

xmlns:xi="http://www.w3.org/2001/XInclude"/>

Каждый из файлов leftxsl и main.xsl содержит шаблон, который обрабатывает элемент xinclude с помощью функции document:

<!— left.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="html"/>

<xsl:template match="xi:include" xmlns:xi="http://www.w3.org/2 001/XInclude"> <xsl:for-each select="document(@href,.)">

<xsl:apply-templates/> </xsl:for-each> </xsl:template>

<xsl:template match="salesBySalesperson"> <html> <head>

<title>Продавцы</title> </head>

<body bgcolor="#FFFFFF" text="#000000"> <table> <tbody>

<xsl:apply-templates/> </tbody> </table> </body> </html> </xsl:template>

<xsl:template match="salesperson"> <tr> <td>

<a href="{concat(‘main.xml#’,@name)}" target="mainFrame"> <xsl:value-of select="@name"/></a> </td> </tr> </xsl:template>

</xsl:stylesheet>

<!– main.xsl –>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html"/>

<xsl:template match="xi:include" xmlns:xi="http://www.w3.org/2 001/XInclude"> <xsl:for-each select="document(@href)">

<xsl:apply-templates/> </xsl:for-each> </xsl:template>

<xsl:template match="salesBySalesperson"> <html> <head>

<title>Продажи для одного продавца<^^^> </head>

<body bgcolor="#FFFFFF" text="#000000"> <xsl:apply-templates/> </body> </html> </xsl:template>

<xsl:template match="salesperson">

<h1><a name="{@name}"><center>Продажи для одного продавца</center></a></h1> <h2><xsl:value-of select="@name"/></h2> <table border="1" cellpadding="3"> <tbody > <tr>

<th>Позиция</th> <th>Продажи (в US $)</th> </tr>

<xsl:apply-templates /> </tbody> </table>

<div style="padding-top:10 0 0"/> </xsl:template>

<xsl:template match="product"> <tr>

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

<td align="right"><xsl:value-of select="@totalSales"/></td> </tr>

</xsl:template>

</xsl:stylesheet>

Таблица стилей main.xsl генерирует именованные теги <a> для каждого про­давца и оставляет между ними большие промежутки с помощью тега <div style="padding-top:1000 "/>. В таблице left.xsl генерируются соответству­ющие ссылки. Тем самым имитируется, хотя и довольно грубо, загрузка отдель­ной страницы для каждого продавца.

См. также

В книге Джени Теннисон XSLT and XPath on the Edge (M&T, 2001) подробно обсуждаются XSLT-преобразования на стороне клиента с участием фреймов и показывается, как с помощью JavaScript можно достичь более впечатляющих результатов.

Мангано Сэл  XSLT. Сборник рецептов. – М.: ДМК Пресс, СПБ.: БХВ-Петербург, 2008. – 864 с.: ил.

По теме:

  • Комментарии