Гостевая
Форум
Разделы
Главная страница
Js скрипты
Php скрипты
Html шаблоны
Книги по Web дизайну
Статьи


Главная страница статей --> Хитрости при программировании php, заметки по базам данных

Преобразование выходного потока XML-данных при выводе в броузер средствами ASP.NET и XSLT.

Источник: realcoding.net

Данная статья смещает акцент с работы 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 Executives 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.На экране видим следующую таблицу

TitlePriceYtd_sales
The Busy Executives Database Guide19.994095
Cooking with Computers: Surreptitious Balance Sheets11.953876
You Can Combat Computer Stress!2.9918722
Straight Talk About Computers19.994095
Silicon Valley Gastronomic Treats19.992032
The Gourmet Microwave2.9922246
The Psychology of Computer Cooking
But Is It User Friendly?22.958780
Secrets of Silicon Valley204095
Net Etiquette
Computer Phobic AND Non-Phobic Individuals: Behavior Variations21.59375
Is Anger the Enemy?10.952045
Life Without Fear7111
Prolonged Data Deprivation: Four Case Studies19.994072
Emotional Security: A New Algorithm7.993336
Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean20.95375
Fifty Years in Buckingham Palace Kitchens11.9515096
Sushi, Anyone?14.994095

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 Executives 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 Algorithm7.993336
Is Anger the Enemy?10.952045
Life Without Fear7111
Prolonged Data Deprivation: Four Case Studies19.994072
You Can Combat Computer Stress!2.9918722

0877

НазваниеЦенаПродажи
Computer Phobic AND Non-Phobic Individuals: Behavior Variations21.59375
Fifty Years in Buckingham Palace Kitchens11.9515096
Onions, Leeks, and Garlic: Cooking Secrets of the Mediterranean20.95375
Silicon Valley Gastronomic Treats19.992032
Sushi, Anyone?14.994095
The Gourmet Microwave2.9922246
The Psychology of Computer Cooking

1389

НазваниеЦенаПродажи
But Is It User Friendly?22.958780
Cooking with Computers: Surreptitious Balance Sheets11.953876
Net Etiquette
Secrets of Silicon Valley204095
Straight Talk About Computers19.994095
The Busy Executives Database Guide19.994095

Очень многих 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- элементам.



Похожие статьи:
- Всплывающее меню для одностраничного портала
- Сложные графики и диаграммы в ASP.NET. Часть третья - HttpHandler/System.Drawing
- Категориальное упорядочение результатов запроса
- Средства безопасности ASP.NET. Аутентификация
- XML+MSSQL+ASP.NET. Часть 1.
- Концептуальный подход к дизайну сайта
- Разница между HttpModule и HttpHandler
- Очищаем HTML от лишних знаков
- Обзор DetailsView
- Лекция 6. Работа с базами данных.
- Лекция 2. Анатомия ASP.NET. ASP.NET в действии.
- Рекомендации по продвижению малых сайтов
- Использование AJAX в ASP.NET


Оглавление | Обсудить на форуме | Главная страница сайта | Карта сайта |
[0.001]