[an error occurred while processing this directive] IT • archiv :: Print

IT • archiv


[an error occurred while processing this directive]

[an error occurred while processing this directive]

Стилизация XML с помощью XSL

[an error occurred while processing this directive](none) [an error occurred while processing this directive](none)[an error occurred while processing this directive] ::
[an error occurred while processing this directive](none)
[an error occurred while processing this directive]([an error occurred while processing this directive] Майкл Болл [an error occurred while processing this directive])

[an error occurred while processing this directive](none)

Использование XSL и сервлетов для стилизации XML данных.

XML-Servlet Tutorial
PDF versionPDF версия
Обзор
Одна из основных особенностей XML в том, что он позволяет разделять контент и его конечное представление. Преположим что вы хотите стилизовать свой XML в нечто презентабельное. Вот когда XSL (Расширяемый язык стилей) приходит нам на помощь — он преобразовывает XML из одного типа документа в другой. Сервлеты же являются замечательной платформой для осуществления таких преобразований. Из этой статьи вы узнаете как преобразовать XML в HTML с использованием сервлетов. (2000 слов)

Да! Мы сильно продвинулись. Год назад вы даже не знали что такое язык XML, но теперь он вездесущ. Вы храните XML в базах данных и у вас появляется потребность вывести эти данные для браузера. Вот где может помочь XSL. XSL поможет вам преобразовать ваш XML код в HTML. Более того, сервлеты обеспечат вас мощным средством для выполнения этих преобразований т.к. они, находясь на сервере, имеют доступ ко всем приемуществам server-side Java. В этой статье мы осветим основы XSL и XSL-процессоров. Если вы недостаточно хорошо знакомы с XML, то возможно сначала вы захотите прочесть замечательную статью Марка Джонсона, Programming XML in Java, Part 1.

В нашем примере мы будем использовать сервлет для преобразования XML в HTML. Если вы хотите больше узнать о сервлетах, то обратитесь к Sun's servlets tutorial (см. Ресурсы).

Замечание
Чтобы скачать полный исходный код для этой статьи, см. Ресурсы.

XML и XSL

Процесс преобразования и форматирования информации в готовый результат называется стилизацией. Чтобы стилизацию сделать возможной, существуют две рекомендации от W3C: XSL преобразования (XSLT), которые позволяют реорганизовывать информацию, а также сам язык XSL, который определяет как форматировать реорганизуемую информацию.

Когда вы используя данные две технологии помещаете ваши XML и XSL данные в XSL-процессор, вы не просто получаете улучшенный вариант вашего XML кода. Вы получаете результат в виде дерева, которое может быть расширено, изменено, либо реорганизовано.

XSL процессор использует так называемый стиль, состоящий из набора XSL команд, который затем он преобразует, используя XML документ. Давайте рассмотрим простой пример.

Ниже мы видим фрагмент XML разметки, описывающий служащего. Он включает в себя имя служащего и его должность. Предположим, что мы хотим представить все это в HTML виде:

<employee id="03432">
   <name>Joe Shmo</name>
   <title>Manager</title>
</employee>

Если мы хотим чтобы наш HTML выглядел следующим образом:

<html>
   <body>
    <p><b>Joe Shmo</b>: Manager</p>
   </body>
</html>

То мы должны использовать стиль, например такой как показано ниже. Стиль может находиться либо в файле, либо в базе данных:

<xsl:stylesheet xmlns:xsl="">
  <xsl:template match="/">
    <html>
      <body>
        <p>
          <b>
            <xsl:value-of select="employee/name"/>
          </b>
          <xsl:text>: </xsl:text>
          <xsl:value-of select="employee/title"/>
        </p>
      </body>
    </html>
  </xsl:template>
</stylesheet>

Общие команды XSL стилей

Стили определяются набором команд XSL. Они создают корректные XML документы. Стили используют механизм совпадения паттернов для нахождения элементов и аттрибутов. Также существуют выражения, используемые для вызова расширений — либо объектов Java, либо JavaScript. Давайте вглянем на некоторые команды XSL.

Описание стилей

Описание стиля состоит из версии и пространства имен. Пространоство имен объявляет префикс для тэгов, которые будут использованы в стиле и местонахождение описания тэгов:

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

Если присутствуют ссылки на какие-либо расширения, то должно быть указано и пространство имен. Например, если вы собираетесь использовать язык Java, то вы должны указать это пространсво имен:

xmlns:java=http://xml.apache.org/xslt/java

Механизм паттернов

При выборе стиля используется паттерн, чтобы обозначить какой нам нужен элемент или аттрибут. Синтаксис прост: указываете ветвь, котрая вам нужна, используя символ / для разделения элементов. Отметим что в примере XML кода (см. выше) мы основывали наш темплейт на /, т.е. на корневой ветви. Однако мы могли основываться на ветви employee. В этом случае выражение могло просто ссылаться на ветвь name вместо employee/name.

Например если у нас есть такой XML код:

<employee id="03432">
 <name>Joe Shmo</name>
 <title>Manager</title>
</employee>

Аттрибуты также могут выбираться. Id служащего мы можем получить, сказав employee/@id. Получить группы ветвей мы можем используя выражение employee/*. Конкретный служащий доступен с помощю выражения employee/@id='03432'.

Паттерны позволяют нам выбирать определенные величины из XML документа. Команда <xsl:value-of select... дает нам возможность выбрать определенную величину для нашего конечного XML документа, как показано на этой таблице:

Команда Результат
<xsl:value-of select= "employee/name"/> Joe Shmo
<xsl:value-of select= "employee/@id"/> 03432
Таблица 1. Доступ к элементам и аттрибутам.

Шаблоны

Шаблоны дают возможность организовывать ветви в XML доументе и выполнять операции с ними. Синтаксис шаблона:

<xsl:template match="nodename">
.
.
.
</xsl:template>

Шаблон основан на имени ветви, поэтому все команды стилей применяемы в этом шаблоне. Мы можем вызывать шаблоны из нашего стиля командой apply-templates:

<xsl:apply-templates select="nodename"/>

А пример c использованием нашего XML служащего будет выглядеть:

<xsl:template match="name"
  <xsl:value-of select="."/>
</xsl:template>

Мы можем вызвать этот шаблон в любом месте где надо сослаться на ветвь name, с помощью данной строки:

<xsl:apply-templates select="name"/>

Логические команды

Существует несколько структур для создания условий и циклов. Давайте взглянем на синтаксис.

Команда Choose

Команда Choose обеспечивает структуру для проверки различных ситуаций.

<xsl:when test="test situation">
    stylesheet commands
  </xsl:when>
  <xsl:otherwise>
    stylesheet commands
  </xsl:otherwise>
</xsl:choose>

Положительный результат при проверке приведет к исполнению комманд в соответствующем блоке стиля. При отрицательном результате во всех блоках будет выполнен блок otherwise. Количество блоков when может быть любым. Блок otherwise должен присутствовать всегда; если вы не хотите исполнять что-то в блоке otherwise, просто скажите <xsl:otherwise/>

Команда If

Команда If выполняет только одиночную проверку условия и не имеет структур типа else. Если вам нужно else, используйте команду choose.

<xls:if test="test situation">
...
</xsl:if>

Циклы (команда for-each)

В отличие от большинства языков со структурами for и while, XSL имеет только команду for-each. Таким образом, вы можете применять циклы к наборам ветвей или же выбирать ветви, к которым вы хотите применить цикл, используя паттерн:

<xsl:for-each 
 select="select statement">
...
</xsl:for-each>

Например, если у вас более одного служащего в XML документе и вы хотите пройтись в цикле по всем менеджерам, то можете использовать такое выражение:

<xsl:for-each  
 select="employee[title='Manager']">
...
</xsl:for-each>

Переменные

Команда variable позволяет установить переменную и получить доступ к ней позже. Механизм расширений использует переменные, чтобы хранить значения получаемые из расширений:

<xsl:variable name="count">
Здесь значение переменной count
</xsl:variable>

Теперь значение переменной count в стиле может быть получено в любой момент, с помощью $count:

<xsl:value-of select="$count"/>

Параметры

Вы можете передавать параметры вашему стилю с помощью тэга param. Вы также можете указать значение по умолчанию в выражении select. Значение по умолчанию это строка, поэтому она должна быть заключена в одиночные кавычки:

<xsl:param name="param1" 
select="'Значение по умолчанию'"/>

Параметры, передаваемые стилю, можно установить на объекте XSLProcessor:

processor.setStylesheetParam 
 ("param1",processor.createXString("value"));

Расширения

Расширения добавляют функциональности к стилю. XSL имеет несколько основных функций:

  • sum() — Складывает значения в определенных ветвях
  • count() — Считает количество ветвей
  • position() — Возвращает позицию текущей ветви в цикле
  • last() — Проверяет последняя ли это нода, возращает значение типа boolean

Если вы хотите дополнительных возможностей, вы должны использовать расширения. Расширения могут быть вызваны везде где могут быть выбраны значения. Расширения к вашему стилю могут быть написаны на Java или JavaScript. В этой статье мы затронем только Java расширения.

Для того чтобы вызывать Java расширения, в объявлении стиля необходимо указать пространство имен Java:

xmlns:java=http://xml.apache.org/xslt/java

Любые вызовы расширений Java должны начинаться с Java:. (Примечание: вам не обязательно называть ваше пространство имен java; вы можете назвать его как хотите.) С расширениями Java можно делать три вещи: создавать инстансы классов, вызвать методы этих классов или просто вызывать статические методы класса.

В таблице 2 показан синтаксис, применяемый для обращения к объектам Java:

Получить копию класса: prefix: class.new (args) Пример: variable myVector select = "java: java.util.Vector.new()"
Вызвать статический метод: prefix: class.methodName (args) Пример: variable myString select = "java: java.lang.String.valueOf (@quantity))"
Вызвать метод объекта: prefix: methodName (object, args) Пример: variable myAdd select = "java: addElement ($myVector, string(@id))"
Таблица 2. Три способа использовать объекты Java (Для более детальной информации о XSL, смотрите Elliotte Harold's The XML Bible в Ресурсах).

API XSL Процессора

Для нашего примера мы будем использовать XSL процессор Xalan от Apache в исполнении Lotus (см. Ресурсы). Следующие классы мы используем в нашем сервлете:

Class com.lotus.xsl.XSLProcessor

com.lotus.xsl.XSLProcessor процессор, реализующий функции, описанные в org.apache.xalan.xslt.XSLTProcessor.

Можно использовать конструктор по умолчанию и запустить обработку с помощью метода process():

void process(XSLTInputSource inputSource, XSLTInputSource stylesheetSource, XSLTResultTarget outputTarget)

Метод process() преобразует исходное дерево в требуемый результат. Метод void reset(), используемый после process() восстанавливает первоначальное состояние процессора. Метод process() перегружен 18 раз. Каждое обозначение дает различный способ обработки вашего XML и XSL. Некоторые возвращают объект типа org.w3c.dom.Document. Я обнаружил что вышеупомянутый метод process() самый удобный; в документации он рекомендован к использованию из-за классов XSLTInputSource (используется для чтения XML или XSL) и XSLTResultTarget (используется для вывода результата), которые исследованы ниже. Class com.lotus.xsl.XSLInputSource

Класс XSLInputSource создается одним из следующих конструкторов:

  • XSLTInputSource(): Конструктор по умолчанию, без агрументов
  • XSLTInputSource(org.xml.sax.InputSource isource): Создает новый входной источник XSLTInputSource из входного источника SAX
  • XSLTInputSource(java.io.InputStream byteStream): Создает новый входной источник из потока байтов
  • XSLTInputSource(org.w3c.dom.Node node): Создает новый входной источник из ветви DOM
  • XSLTInputSource(java.io.Reader characterStream): Создает новый входной источник из потока символов.
  • XSLTInputSource(java.lang.String systemId): Создает новый входной источник с помощью идентификатора системы.

Class com.lotus.xsl.XSLResultTarget

Класс XSLResultTarget создается одним из следующих конструкторов:

  • XSLTResultTarget(): Конструктор по умолчанию, без агрументов
  • XSLTResultTarget(org.xml.sax.DocumentHandler handler): Создает новый класс из обработчика SAX документа, который будет обрабатывать результирующие события
  • XSLTResultTarget(org.w3c.dom.Node n): Создает новый класс из потока символов
  • XSLTResultTarget(java.io.OutputStream byteStream): Создает новый класс из потока байтов
  • XSLTResultTarget(java.lang.String fileName): Создает новый с именем файла
  • XSLTResultTarget(java.io.Writer characterStream): Создает новый класс из потока символов

API также включает классы, которые позволяют вам прослушивать события — проблемы или события документа, например — во время обработки.

Подведем итог

Теперь когда у нас есть основной обзор XSL API и XSL стилей, давайте взглянем на проблему которую данные технологии могут помочь нам решить. В этом примере мы имеем серверный процесс, который использует XML для хранения данных о сделках. Существует деловая потребность в возможности проанализировать сделки за день. Решение не должно влиять на текущие процессы и процедуры работы с данными. Вот некоторые из возможных решений, использующих XSL:

  1. Создать периодически запускаемую на сервере программу, которая будет использовать XSL для преобразования XML в HTML. Конечные HTML файлы будут сохраняться на файловый сервер, где они будут доступны через браузер.
  2. Если у вас есть контроллируемый набор пользователей, убедитесь что они имеют браузеры с поддержкой XSL. В этом случае ваш XML будет включать заголовок, говорящий какой именно XSL документ следует использовать, позволяя браузеру сделать для вас все преобразование.
  3. Использовать XSL в каком-либо серверном средстве обработки, таком как сервлеты. Взять XML код из файла, либо из базы данных, либо из очереди сообщений и затем стилизовать его с помощью XSL.

Мы будем использовать третий подход, но первый и второй подходы также годяться. Первый подход должен решить все проблемы со скоростью,

но он не обеспечивает динамического создания HTML, что сделает наше приложение специализированным. Второй подход скоро даст реальные возможности — Internet Explorer 5 может выполнять XSL преобразования, а Netscape анонсировал что это будет возможно уже в следующем релизе. Однако не все ваши пользователи хотят иметь новейшие браузеры и мы все еще должны делать всю обработку на сервере.

Двигаясь дальше, давайте взглянем на XML схему наших сделок:

<!ELEMENT orders (invoice)+>
<!ELEMENT invoice (item+,name,address+)>
<!ELEMENT item EMPTY>
<!ELEMENT name (#PCDATA)>
<!ELEMENT address (street, city, state, zip)>
<!ELEMENT street (#PCDATA)>
<!ELEMENT city (#PCDATA)>
<!ELEMENT state (#PCDATA)>
<!ELEMENT zip (#PCDATA)>
<!ATTLIST invoice
  number CDATA #REQUIRED
  orderDate CDATA #REQUIRED
  shipDate CDATA #REQUIRED>
<!ATTLIST item
  part CDATA #REQUIRED
  quantity CDATA #REQUIRED
  cost CDATA #REQUIRED>
<!ATTLIST address
  type (shipping|billing|other) #REQUIRED>
Замечание
XSL не требует DTD для своей работы — хорошая особенность. Таким образом при небольших изменениях в схеме можно использовать те же стили.

В нашем примере будет слздано 4 стиля, каждый представляет отдельный экран:

  1. Экран сделки: Список сделок за каждый день, включает номер накладной, имя клиента и сумму итога.
  2. Экран проданного продукта: Список всех проданных продуктов за каждый день, включая количество.
  3. Экран детального просмотра: Смесь из экранов 1 и 2. Когда пользователь нажимает на номер накладной, он видит подробности сделки.
  4. Экран с XML: Показывает XML код, который мы обрабатываем.

В этих примерах не будет вращающихся лого, чтобы показать мощь XSL не засоряя разметку графикой. HTML вызывающий сервлет будет использовать фреймы. Левый фрейм будет иметь список доступных стилей. При выборе стиля сервлету будет послан запрос. Потом сервлет откроет XML и стиль и с помощью XSLProcessor выполнит перевод. Перевод будет иметь форму HTML, выдаваемого браузеру. Давайте сначала рассмотрим экран сделок, показывающий список накладных, далее экран детальной информации о сделках, показывающий подробности сделки.

Экран ниформации о сделках

Экран ниформации о сделках — Список сегодняшних накладных:

<xsl:stylesheet
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:java="http://xml.apache.org/xslt/java"
                exclude-result-prefixes="java"
                version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/orders">
  <html>
    <h1>Today's Invoices</h1>
    <body>
      <table border="on" cellspacing="1" 
       cellpadding="5">
      <thead>
      <th>Invoice Number</th>
      <th>Customer Name</th>
      <th>Total Purchase</th>
      </thead>
      <tbody>
      <xsl:for-each select="invoice">
      <tr>
      <td>
      <xsl:element name="a">
        <xsl:attribute
          name="href"><xsl:text>xsl?
          stylesheet=detail&invoiceNum=
          </xsl:text>
          <xsl:value-of select="@number"/>
          </xsl:attribute>
        <xsl:value-of select="@number"/>
      </xsl:element>
      </td>
      <td><xsl:value-of select=
             "name"/></td>
      <td>
      <xsl:value-of select=
            "java:SumInvoice.summ(item)"/>
      </td>
      </tr>
      </xsl:for-each>
      </tbody>
      </table>
    </body>
  </html>
</xsl:template>
</xsl:stylesheet>

На Рисунке 1 показан результат.

Стиль 1: Вывод информации о сделках.
Рисунок 1. Стиль 1: Вывод информации о сделках.

Экран детальной информации о сделке

Сейчас мы остановим ваше внимание на стиле для экрана детальной информации:

<xsl:stylesheet
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:java="http://xml.apache.org/xslt/java"
                exclude-result-prefixes="java"
                version="1.0">
<xsl:param name="invoiceNum" select="string('none')"/>
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<html>
  <body>
     <table border="on" cellspacing="1" cellpadding="5">
     <xsl:for-each select="orders/invoice[@number=$invoiceNum]">
       <tr>
         <td>
           <table border="on" cellspacing="1" cellpadding="5">
             <tr><td><b>
             Invoice Number:</b>
             <xsl:value-of select="@number"/>
             </td><td colspan="3">
             <xsl:value-of select="name"/>
             </td></tr>
             <tr>
               <td colspan="4">
               <xsl:apply-templates select="address"/>
               </td>
             </tr>
             <tr><td colspan="4"><b>
             Items</b>
             </td></tr>
            <tr><td>Part</td>
            <td>Quantity</td>
            <td>Cost</td>
            <td>Subtotal
            </td></tr>
             <xsl:for-each select="item">
               <tr>
                 <td>
                 <xsl:value-of select="@part"/>
                 </td>
                 <td>
                 <xsl:value-of select="@quantity"/>
                 </td>
                 <td><xsl:value-of select="@cost"/></td>
                 <td>
                 <xsl:value-of select="@quantity * @cost"/>
                 </td>
               </tr>
               <xsl:if test="last()">
               </xsl:if>
             </xsl:for-each>
               <tr><td><b>
               <xsl:text>Total</xsl:text>
               </b></td>
                 <td>
                 <xsl:value-of select=
                     "sum(item/@quantity)"/>
                 </td>
                 <td><xsl:text></xsl:text></td>
                 <td>
                   <xsl:value-of select=
                     "java:SumInvoice.summ(item)"/>
                 </td>
               </tr>
           </table>
         </td>
       </tr>
     </xsl:for-each>
     </table>
  </body>
</html>
</xsl:template>
<xsl:template match="address">
<table>
  <tr><td><i>
    <xsl:choose>
      <xsl:when test="@type='shipping'">
        <xsl:text>Shipping Address</xsl:text>
      </xsl:when>
      <xsl:when test="@type='billing'">
        <xsl:text>Billing Address</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:text>Other Address</xsl:text>
      </xsl:otherwise>
    </xsl:choose></i>
  </td></tr>
  <tr><td colspan="4">
  <xsl:value-of select="street"/></td></tr>
  <tr><td colspan="4">
  <xsl:value-of select="city"/>
  <xsl:text>
  </xsl:text>
  <xsl:value-of select="state"/>,
  <xsl:value-of select="zip"/>
  </td></tr>
</table>
</xsl:template>
</xsl:stylesheet>

Результаты на Рисунке 2

Стиль 3: Вывод детальной информации
Рисунок 2. Стиль 3: Вывод детальной информации

Обработка

Наш сервлет будет наследовать Java класс HTTPServlet и применять методы doPost() и doGet(). XSLInputSource позволяет нам просто дать XSLProcessor'у объект java.io.Reader — идеально в случае если наши XML и XSL находяться в обычных файлах. В ином случае мы можем использовать StringReader. XSLInputSource также хорошо воспримет org.w3c.dom.Node. XSLTResultTarget выведет все в OutputStream — это удобно когда мы можем получить OutputStream из HTTPResponse.

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import com.lotus.xsl.XSLTInputSource;
import com.lotus.xsl.XSLTResultTarget;
import com.lotus.xsl.XSLProcessor;
import org.xml.sax.SAXException;
public class XSLServlet extends HttpServlet {
  public void init(ServletConfig config)
                     throws ServletException {
    super.init(config);
  }
  //By redirecting our doGets to the doPost
  //method we can have a stylesheet
  //executed from a link
  //ex. <a
href="xsl?stylesheet=detail&invoiceNum=00002">00002
  public void doGet
   (HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    doPost(request, response);
  }
  //Process the HTTP Post request
  public void doPost
   (HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {
    PrintWriter out = new PrintWriter (response.getOutputStream());
    //Get the stylesheet selected by the user
    String stylesheet = request.getParameter("stylesheet");
    //Get the invoice number selected by the user,
    //this is used only for certain
    //stylesheets. If it is not present,
    //the stylesheet won't use it.
    String invoiceNum = request.getParameter("invoiceNum");
    //Prepare FileReaders for the stylesheet and XML
    FileReader xslReader = new
FileReader(".\\javaworld\\xsl\\"+stylesheet+".xsl");
    FileReader xmlReader = new
FileReader(".\\javaworld\\xml\\"+"invoice.xml");
    response.setContentType("text/html");
    try
    {
      //Create an instance of an XSLProcessor
      XSLProcessor proc = new XSLProcessor();
      //Set the invoice number parameter
      proc.setStylesheetParam("invoiceNum", invoiceNum);
      //Process the stylesheet, all the output will go straight
      // out to the browser.
      proc.process(new XSLTInputSource(xmlReader),new
XSLTInputSource(xslReader),new XSLTResultTarget(out));
    }
    catch (SAXException saxE)
    {
      out.write(saxE.getMessage());
      saxE.printStackTrace(out);
    }
    out.close();
  }
  //Get Servlet information
  public String getServletInfo() {
    return "XSLServlet Information";
  }
}

Вот и все!

Выводы

Вы только что узнали как извлечь HTML из XML с помощью XSL. Но как я упоминал в начале статьи, XSL можно использовать для преобразования XML в различные типы документов — XML в HTML, HTML в XML, HTML в HTML, XML в DSML (Язык Разметки Сервиса Каталогов), и т.д. Самая полезная особенность XSL: его не нужно компилировать. Принцип, по кторому работает наш пример с сервлетами в том что мы можем добавлять стили в нашу папку стилей, а потом добалять стиль к списку стилей в нашем HTML. Другое полезное применеие XSL: взять набор java.sql.Result и преобразовать его в простой документ XML, в которм имя запроса это корневая ветвь, а каждая строка в таблице результатов это элемент нашего XML документа. Подэлементы каждого такого элемента (строки) это столбцы и значения из этой строки. Взяв такой простой, хорошо структурированный XML документ, мы можем просто применить к нему XSL, создав XML документ, сообразный желаемой схеме. Это может быть полезно для EDI (Электронный Интерфейс Данных) или в случае если вам надо извлечь данные из реляционной БД, такой как XML. Несколько слов о скорости: XSLProcessor работает очень быстро; он выполняет преобразования за доли секунды. Скорость снижается когда стили выполняют много сложных операций. Входной XML должен быть достаточно большим — около 100 Кб — пока вы заметите значительное снижение в скорости. И в завершение, XSL позволяет превратить XML в HTML без особых усилий. Но его возможности гораздо шире. Механизм расширений добавляет функциональности к основному XSL. Использование сервлетов для обработки XSL поможет вам разделить контент и его представление на экране.

Об авторе

Michael Ball is a senior consultant for Software Architects in Cincinnati, assisting in Java and XML training. A Sun Certified Java 2 Developer and IBM Certified XML Developer, Michael has been working on projects utilizing XML, XSL, Servlets, and EJBs for the last year.

Ресурсы

Reprinted with permission from the June 2000 edition of JavaWorld magazine. Copyright © ITworld.com, Inc., an IDG Communications company.
View the original article at: http://www.javaworld.com/ jw-06-2000/jw-0630-xsl.html

[an error occurred while processing this directive]
[an error occurred while processing this directive] Перевод на русский © Дмитрий Князев, 2000
< Вернуться на caйт :: Copyright © 1999 — 2010, IT • archiv.