Visual Basic, .NET, ASP, VBScript
 

   
 
Описание для автора не найдено
 
     
   
 

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

Автор: Измайлов Феликс (qstart@narod.ru)

Источник: http://rsl.bankir.ru/


Данная статья смещает акцент с работы 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- элементам.

 
     

   
   
     
  VBNet рекомендует