Данная статья
смещает акцент с работы ASP.NET и MSSQL на использование языка шаблонов
XSLT, но в данной связке данные технологии представляют собой мощное и
гибкое средство представления данных. Наложение шаблонов позволяет (и
что будет показано в данной статье) превратить поток в таблицу HTML,
преобразовать в Excel-файл, и открыть его в браузере. Небольшая
выдержка из прошлой статьи, для логичного продолжения материала. У нас
есть код который выводит в браузер XML-документ (primer.aspx), немного
изменим состав полей, для краткости вывода.
<%@ Page Language="VB" %>
<%@ import Namespace="Microsoft.Data.SqlXML" %>
<script runat="server">
Sub Page_Load(sender As Object, e As EventArgs)
Dim cmd as SqlXmlCommand
cmd = New SqlXmlCommand("Provider=SQLOLEDB;server=(local);database=pubs;uid=sa;password=sa")
cmd.CommandText ="SELECT Title,Price,Ytd_sales FROM Titles FOR XML AUTO"
Response.ContentType = "text/xml"
cmd.RootTag = "root"
Response.Clear()
cmd.ExecuteToStream(Response.OutputStream)
End SUb
</script>
В результате выполнения запроса получаем:
<?xml version="1.0" encoding="utf-8" ?>
<root>
<Titles Title="The Busy Executive's Database Guide" Price="19.99" Ytd_sales="4095" />
<Titles Title="Cooking with Computers: Surreptitious Balance Sheets" Price="11.95" Ytd_sales="3876" />
<Titles Title="You Can Combat Computer Stress!" Price="2.99" Ytd_sales="18722" />
<Titles Title="Straight Talk About Computers" Price="19.99" Ytd_sales="4095" />
<Titles Title="Silicon Valley Gastronomic Treats" Price="19.99" Ytd_sales="2032" />
<Titles Title="The Gourmet Microwave" Price="2.99" Ytd_sales="22246" />
<Titles Title="The Psychology of Computer Cooking" />
<Titles Title="But Is It User Friendly?" Price="22.95" Ytd_sales="8780" />
<Titles Title="Secrets of Silicon Valley" Price="20" Ytd_sales="4095" />
<Titles Title="Net Etiquette" />
<Titles Title="Computer Phobic AND Non-Phobic Individuals: Behavior Variations" Price="21.59" Ytd_sales="375" />
<Titles Title="Is Anger the Enemy?" Price="10.95" Ytd_sales="2045" />
<Titles Title="Life Without Fear" Price="7" Ytd_sales="111" />
<Titles Title="Prolonged Data Deprivation: Four Case Studies" Price="19.99" Ytd_sales="4072" />
<Titles Title="Emotional Security: A New Algorithm" Price="7.99" Ytd_sales="3336" />
<Titles Title="Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean" Price="20.95" Ytd_sales="375" />
<Titles Title="Fifty Years in Buckingham Palace Kitchens" Price="11.95" Ytd_sales="15096" />
<Titles Title="Sushi, Anyone?" Price="14.99" Ytd_sales="4095" />
</root>
Напишем следующий текст, и сохраним его в файле primer.xsl
<?xml version="1.0" encoding="WINDOWS-1251"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
version="1.0">
<xsl:template match="/">
<Table border="1" cellpadding="0" id="fxTable" style="font: 8pt verdana" >
<!-- Печатаем названия столбцов - берем из первой строки -->
<xsl:for-each select="//*[1]/@*">
<!-- Выводим название аттрибута, т.е. название столбца -->
<th><xsl:value-of select="name()"/></th>
</xsl:for-each>
<!-- Применяем шаблон для всех элементов документа -->
<xsl:apply-templates select="//*"/>
</Table>
</xsl:template>
<xsl:template match="//*">
<!-- Если узел имеет родителя, т.е. отсекаем корневой элемент -->
<xsl:if test="parent::*">
<!-- Выводим строку таблицы -->
<tr>
<!-- Перебираем в строке все аттрибуты и выводим их значения -->
<xsl:for-each select="@*">
<td><xsl:value-of select="."/></td>
</xsl:for-each>
</tr>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
В файл primer.aspx добавим инструкцию
cmd.XslPath = Server.MapPath("primer.xsl")
и закомментарим строку Response.ContentType = "text/xml",
по умолчанию поток будет выводится в формате HTML.
На экране видим следующую таблицу
Title |
Price |
Ytd_sales |
The Busy Executive's Database Guide |
19.99 |
4095 |
Cooking with Computers: Surreptitious Balance Sheets |
11.95 |
3876 |
You Can Combat Computer Stress! |
2.99 |
18722 |
Straight Talk About Computers |
19.99 |
4095 |
Silicon Valley Gastronomic Treats |
19.99 |
2032 |
The Gourmet Microwave |
2.99 |
22246 |
The Psychology of Computer Cooking |
But Is It User Friendly? |
22.95 |
8780 |
Secrets of Silicon Valley |
20 |
4095 |
Net Etiquette |
Computer Phobic AND Non-Phobic Individuals: Behavior
Variations |
21.59 |
375 |
Is Anger the Enemy? |
10.95 |
2045 |
Life Without Fear |
7 |
111 |
Prolonged Data Deprivation: Four Case Studies |
19.99 |
4072 |
Emotional Security: A New Algorithm |
7.99 |
3336 |
Onions, Leeks, and Garlic: Cooking Secrets of the
Mediterranean |
20.95 |
375 |
Fifty Years in Buckingham Palace Kitchens |
11.95 |
15096 |
Sushi, Anyone? |
14.99 |
4095 |
Primer.xsl – универсальный шаблон, который превращает XML-данные
(при режиме AUTO) в таблицу, с названиями столбцов равными названиям
полей. В общем, сам по себе пример не очень ценный. Связка DataSource и
DataGrid делают все тоже самое. Ценность XML проявляется при
нестандартных ситуациях. Обратимся к примеру из предыдущей статьи, где
происходит вывод публикаций в разрезе Издателей.
<?xml version="1.0" encoding="utf-8" ?>
<root>
<Издатель Номер="0736">
<Книга Название="Emotional Security: A New Algorithm" Цена="7.99" Продажи="3336" />
<Книга Название="Is Anger the Enemy?" Цена="10.95" Продажи="2045" />
<Книга Название="Life Without Fear" Цена="7" Продажи="111" />
<Книга Название="Prolonged Data Deprivation: Four Case Studies" Цена="19.99" Продажи="4072" />
<Книга Название="You Can Combat Computer Stress!" Цена="2.99" Продажи="18722" />
</Издатель>
<Издатель Номер="0877">
<Книга Название="Computer Phobic AND Non-Phobic Individuals: Behavior Variations" Цена="21.59" Продажи="375" />
<Книга Название="Fifty Years in Buckingham Palace Kitchens" Цена="11.95" Продажи="15096" />
<Книга Название="Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean" Цена="20.95" Продажи="375" />
<Книга Название="Silicon Valley Gastronomic Treats" Цена="19.99" Продажи="2032" />
<Книга Название="Sushi, Anyone?" Цена="14.99" Продажи="4095" />
<Книга Название="The Gourmet Microwave" Цена="2.99" Продажи="22246" />
<Книга Название="The Psychology of Computer Cooking" />
</Издатель>
<Издатель Номер="1389">
<Книга Название="But Is It User Friendly?" Цена="22.95" Продажи="8780" />
<Книга Название="Cooking with Computers: Surreptitious Balance Sheets" Цена="11.95" Продажи="3876" />
<Книга Название="Net Etiquette" />
<Книга Название="Secrets of Silicon Valley" Цена="20" Продажи="4095" />
<Книга Название="Straight Talk About Computers" Цена="19.99" Продажи="4095" />
<Книга Название="The Busy Executive's Database Guide" Цена="19.99" Продажи="4095" />
</Издатель>
</root>
Если руководство захочет видеть информацию по каждому издателю в
отдельной таблице, то сразу возникает вопрос – количество издателей
(таблиц) жестко не определено. Оно может меняться. Конечно, можно
динамически добавлять DataGrid’ы, но на XML проще и кода меньше. Кстати,
давайте выведем эту информация в HTML-таблицы. Вот шаблон.
<?xml version="1.0" encoding="WINDOWS-1251"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
version="1.0">
<xsl:template match="/">
<xsl:for-each select="//Издатель">
<h2>
<xsl:value-of select="@Номер"/>
</h2>
<Table border="1" cellpadding="3" id="fxTable" style="font: 8pt verdana" >
<xsl:for-each select="*[1]/@*">
<!-- Выводим название аттрибута, т.е. название столбца -->
<th><xsl:value-of select="name()"/></th>
</xsl:for-each>
<xsl:apply-templates select="Книга"/>
</Table>
<br/>
</xsl:for-each>
</xsl:template>
<xsl:template match="Книга">
<tr>
<!-- Перебираем в строке все аттрибуты и выводим их значения -->
<xsl:for-each select="@*">
<td><xsl:value-of select="."/></td>
</xsl:for-each>
</tr>
</xsl:template>
</xsl:stylesheet>
Теперь при появлении нового издателя, не надо переделывать ни код, ни
шаблон. Автоматически появится новая таблица с информацией.
0736
Название |
Цена |
Продажи |
Emotional Security: A New Algorithm |
7.99 |
3336 |
Is Anger the Enemy? |
10.95 |
2045 |
Life Without Fear |
7 |
111 |
Prolonged Data Deprivation: Four Case Studies |
19.99 |
4072 |
You Can Combat Computer Stress! |
2.99 |
18722 |
0877
Название |
Цена |
Продажи |
Computer Phobic AND Non-Phobic Individuals: Behavior
Variations |
21.59 |
375 |
Fifty Years in Buckingham Palace Kitchens |
11.95 |
15096 |
Onions, Leeks, and Garlic: Cooking Secrets of the
Mediterranean |
20.95 |
375 |
Silicon Valley Gastronomic Treats |
19.99 |
2032 |
Sushi, Anyone? |
14.99 |
4095 |
The Gourmet Microwave |
2.99 |
22246 |
The Psychology of Computer Cooking |
1389
Название |
Цена |
Продажи |
But Is It User Friendly? |
22.95 |
8780 |
Cooking with Computers: Surreptitious Balance Sheets |
11.95 |
3876 |
Net Etiquette |
Secrets of Silicon Valley |
20 |
4095 |
Straight Talk About Computers |
19.99 |
4095 |
The Busy Executive's Database Guide |
19.99 |
4095 |
Очень многих ASP.NET-программистов интересует вопрос представления
данных клиенту в виде Excel-документа. Это дает клиенту возможность
дальнейшего манипулирования данными самостоятельно, без участия
программиста.
Как превратить XML-поток в XML-документ, который распознается
браузером как Excel-таблица, покажем на примере того же запроса в начале
этой статьи.
Сразу скажу, что многие вопросы можно решить, проделав элементарные
действия. В Excel отформатировать внешний вид документа (фонт, цвет,
рамки ячеек и пр.), затем сохранить в XML виде, и проанализировать
текст, что и как происходит.
В файле primer.aspx заменим строку Response.ContentType = "text/xml"
на Response.ContentType = "application/vnd.ms-excel"
Следующий шаблон превратит наши данные в браузере в Excel-таблицу
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
<xsl:template match="/">
<xsl:processing-instruction name=">
<xsl:text>progid="Excel.Sheet"</xsl:text>
</xsl:processing-instruction>
<Workbook>
<Worksheet ss:Name="Sheet 1">
<Table>
<Row>
<xsl:for-each select="//*[1]/@*">
<Cell>
<Data ss:Type="String"><xsl:value-of select="name()"/></Data>
</Cell>
</xsl:for-each>
</Row>
<xsl:apply-templates select="//*"/>
</Table>
</Worksheet>
</Workbook>
</xsl:template>
<xsl:template match="//*">
<xsl:if test="parent::*">
<Row>
<xsl:for-each select="@*">
<Cell><Data ss:Type="String"><xsl:value-of select="."/></Data></Cell>
</xsl:for-each>
</Row>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
У данного шаблона есть несколько недостатков. Первое, в нем нельзя вставлять комментарии ( вида <!—ля-ля -->) и второе, все данные выводятся в текстовом виде, т.е. ячейки, куда выводится числовая информация, будут отформатированы как текст. Что бы исправить этот недостаток, надо изменить алгоритм, и привязаться к анализу имен атрибутов. Теряется универсальность, но данные выводятся согласно их типу.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
<xsl:template match="/">
<xsl:processing-instruction name=">
<xsl:text>progid="Excel.Sheet"</xsl:text>
</xsl:processing-instruction>
<Workbook>
<Styles>
<Style ss:ID="s22"><NumberFormat ss:Format="Short Date"/></Style>
<Style ss:ID="s23"><NumberFormat ss:Format="Standard"/></Style>
</Styles>
<Worksheet ss:Name="Sheet 1">
<Table>
<Row>
<xsl:for-each select="//*[1]/@*">
<Cell>
<Data ss:Type="String">
<xsl:value-of select="name()"/>
</Data>
</Cell>
</xsl:for-each>
</Row>
<xsl:apply-templates select="//*"/>
</Table>
</Worksheet>
</Workbook>
</xsl:template>
<xsl:template match="//*">
<xsl:if test="parent::*">
<Row>
<xsl:for-each select="@*">
<xsl:choose>
<xsl:when test="name()='pub_id' or
name()='advance' or
name()='royalty' or
name()='ytd_sales'">
<Cell><Data ss:Type="Number"><xsl:value-of select="."/></Data></Cell>
</xsl:when>
<xsl:when test="name()='price'">
<Cell ss:StyleID="s23"><Data ss:Type="Number"><xsl:value-of select='.'/></Data></Cell>
</xsl:when>
<xsl:when test="name()='pubdate'">
<Cell ss:StyleID="s22"><Data ss:Type="DateTime"><xsl:value-of select="."/></Data></Cell>
</xsl:when>
<xsl:otherwise>
<Cell><Data ss:Type="String"><xsl:value-of select="."/></Data></Cell>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</Row>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
В этом шаблоне применяется форматирование ячеек, стили определяются в
секции <Styles>. Все тонкости применения стилей форматирования можно
найти на ссылке
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnexcl2k2/html/odc_xmlss.asp
или с помощью сохранения таблицы с отформатированными ячейками как
XML-документ, и дальнейшим поиском соответствующего стиля.
В общих чертах эта вся технология превращения XML-потока либо HTML,
либо в Excel-файл. Всё дальнейшее совершенствование коснется только
внешнего вида (т.е. применение стилей форматирования) или обработки
XML-данных, а это уже напрямую выводит на изучение языка XSLT.
В заключение статьи приведу координаты книги по данному языку. Автор,
один из сильнейших специалистов в этой области (обработке XML).
Майкл Кей, XSLT. Спавочник программиста. Пер. с англ.-
СПб:Символ-Плюс, 2002.-1016 с., ил. ISBN 5-93286-039-1
Вот по этой ссылке
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odc_xl2003_ta/html/odc_XLxmlhowto_.asp
лежит теория и примеры связки ASP.old + XML = Excel-таблица.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnexcl2k2/html/odc_xmlss.asp
- справочник по SpeadSheet- элементам. |