zoukankan      html  css  js  c++  java
  • XSLT快速参考

    1 前言

    我们用一个简单的XSLT样式表作为例子介绍了XSLT的概要。当然,XSLT所拥有的元素并不仅限于xsl:template、xsl:apply-templates、xsl:value-of。为了实行转换,XSLT准备了各种各样的元素。本章将以最常用的元素为中心举例说明。

    另外,本文中并不准备介绍元素的全部属性。详情请参见W3C标准的原文[1]及译文[2]等。

    在XSLT中经常会用到一种被称为XPath的描述方法。首先从XPath的概要开始介绍。

    2 XPath是什么?

    XPath是树结构的一种描述方法。在创建XSL样式表时经常使用XPath。

    2.1 树结构

    XML文档表示的数据组成数结构。用XLST进行转换,也就是从源文档的树(源树)生成转换后的树(目标树)的意思。这个转换以树结构的节点为基础来进行。

    节点有几种,主要为:

    • 表示根的“根节点”
    • 表示元素的“元素节点”
    • 表示属性的“属性节点”
    • 表示文本的“文本节点”
    • 表示注释的“注释节点”

    使用像这样的各种各样的节点来表示树的位置的描述方法称为XPath。

    2.2 XPath表达式

    创建XSLT样式表时经常使用的XPath表达式如表1所示。所谓的上下文节点,就是由上下文构成的节点,可以理解为“处理对象”。另外,今后会出现“当前节点”的概念,可以理解为“被选中的节点”。 1

    表1: 常用的XPath表达式
    记号 含义
    a 上下文节点的a元素
    * 上下文节点的所有元素
    a/b 以上下文节点的a元素为父节点的b元素
    a//b 以上下文节点的a元素为祖先的b元素
    a|b 上下文节点的a元素和b元素
    a[表达式] 符合表达式的上下文节点的a元素
    . 上下文节点
    .. 上下文节点的父节点
    / 根节点
    @a 上下文节点的a属性
    @* 上下文节点的所有属性
    node() 所有节点
    text() 文本节点

    描述类似于UNIX的路径描述。例如,

    <html>
      <body>
        <a href="sample.html">示例</a>
        <ul>
          <li>项目A</li>
          <li>项目B</li>
        </ul>
      </body>
    </html>
    

    中,表示元素a的XPath表达式为

    /html/body/a

    此外,若表示a元素的href属性,则为

    /html/body/a/@href

    表中a[表达式]是符合表达式的a项目的意思,例如表示第一个li项目时使用

    /html/body/ul/li[1]

    3 定义样式表的元素

    XSLT样式表使用XML文档的格式创建。因此,必须要遵从XML文档的描述规则。XML文档中必须存在的元素只有根元素。在XSLT样式表中的根元素就是xsl:stylesheet元素。基本代码如下所示:

    <xsl:stylesheet
      version = "版本号">
      <!-- 内容: (xsl:import*, 顶层元素) -->
    </xsl:stylesheet>
    

    4 模板规则

    XSLT样式表可以说是模板规则的集合。

    4.1 模板规则的定义

    模板规则使用xsl:template元素进行定义。它的属性包括match、name、priority和mode。其中最重要的是match属性,该属性规定了节点的样式。若没有指定name属性的话,就必须指定match属性。基本的代码如下所示。

    <xsl:template 
      match = "样式"
      name = "名称">
      <!-- 内容: (xsl:param*, 模板) -->
    </xsl:template>
    

    name属性将在调用命名模板时使用。关于命名模版将在后面讲述。

    4.2 应用模板规则

    我们使用xsl:apply-template元素来应用模板规则。它包含select和mode属性。基本的代码如下所示:

    <xsl:apply-templates
      select = "节点集合表达式">
      <!-- 内容: (xsl:sort | xsl:with-param)* -->
    </xsl:apply-templates>
    

    后面将讲到的排序操作等之外的情况下该元素不需要内容,因此空元素标记可以写成以下的形式:

    <xsl:apply-templates select="节点集合表达式"/>
    

    未指定select属性时,当前节点为所有的子节点。

    通常,仅在处理当前节点的子孙节点时使用该元素。这样就不会发生无法终了的无限循环。不能定义如下例所示的无限循环模版:

    <xsl:template match="x">
      <xsl:apply-templates select="."/>
    </xsl:template>
    

    4.3 命名模版

    带有name属性的模板规则可以通过模版名称来调用。

    <xsl:call-template
      name = "名称">
      <!-- 内容: xsl:with-param* -->
    </xsl:call-template>
    

    例如,定义下例所示的模板规则时,

    <xsl:template name="hello">
      你好
    </xsl:template>
    

    可以以下面的方式调用:

    <xsl:call-template name="hello"/>
    

    输出为:

    你好
    

    4.4 匹配冲突

    某个指定的表达式可能会出现多个匹配结果。这时根据优先度来决定应用哪个模板。定义模板规则时可通过设置priority属性来显式地指定模板优先度。如未指定,将采用默认优先度。关于默认优先度的计算方法请参见参考文献[1]。一般来说限制性强的表达式优先度较高。例如“a”的优先度要高于“*”。

    4.5 内嵌模版规则

    内嵌模板规则即为默认模板规则,不匹配任何模板规则的节点将由它来处理。这种机制保证了即使在不定义任何模板规则的情况下,模版处理也能递归地进行下去。

    应用于元素节点和根节点的内嵌模板规则如下所示。

    <xsl:template match="*|/">
      <xsl:apply-templates/>
    </xsl:template>
    

    应用于文本节点和属性节点的内嵌模板规则如下所示。

    <xsl:template match="text()|@*">
      <xsl:value-of select="."/>
    </xsl:template>
    

    对于其他节点(如注释节点等)不做任何处理。

    这种模板规则将把文本节点内容全部输出。将代码1所示的XSLT样式表应用到某个XML文档上之后,将生成以doc为根节点、文本节点为内容的XML文档。

    代码1: builtin.xsl
    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:template match="/">
        <doc>
          <xsl:apply-templates/>
        </doc>
      </xsl:template>
    </xsl:stylesheet>
    

    5 输出

    虽然称为“输出”,但实际的意思是“生成目标树的节点”。可以使用源树生成节点,也可以直接生成节点。

    5.1 取出文本

    xsl:value-of元素可以将指定的节点的值作为字符串来输出。必须要指定select属性。

    <xsl:value-of
      select = "字符串表达式"/>
    

    指定的树种包含其它元素时,文本节点以外的节点将被忽略,仅输出文本。例如,

    <p>.com时代的<b>IT</b>杂志</p>
    

    对该树应用

    <xsl:value-of select="p"/>
    

    时,输出为

    .com时代的IT杂志
    

    选择当前节点可以使用“.”。若将

    <a href="http://www.gihyo.co.jp">
      技术评论公司</a>
    

    作为当前节点,那么

    <xsl:value-of select="."/>的URL是
    <xsl:value-of select="@href"/>。
    

    的输出为

    技术评论公司的URL是
    http://www.gihyo.co.jp。
    

    5.2 节点复制

    xsl:value-of元素将节点的值转换为字符串。与此相对,xsl:copy-of元素将复制节点,节点中包含的子元素原封不动。基本的代码如下所示。

    <xsl:copy-of
      select = "表达式"/>
    

    例如、

    <p>.com时代的<b>IT</b>杂志</p>
    

    对此应用

    <xsl:copy-of select="p"/>
    

    的话,输出为

    <p>.com时代的<b>IT</b>杂志</p>
    

    5.3 属性值模板

    需要生成属性值时,可以使用大括号{}将表达式括起来。2

    例如,想由

    <link>
      <title>技术评论公司</title>
      <url>http://www.gihyo.co.jp/</url>
    </link>
    

    生成如下的HTML链接时,

    <a href="http://www.gihyo.co.jp/">
      技术评论公司
    </a>
    

    可以定义如下的模板规则。

    <xsl:template match="link">
      <a href="{url}">
       <xsl:value-of select="title"/>
      </a>
    </xsl:template>
    

    5.4 生成文本

    xsl:text元素可以生成文本节点。由于生成文本时直接将文本写出即可,所以一般情况下该元素不使用。但是若需要令输出的转义字符失效的话就需要使用该元素。基本代码如下所示。

    <xsl:text
      disable-output-escaping = "yes" | "no">
      <!-- 内容: #PCDATA -->
    </xsl:text>
    

    通过disable-output-escaping属性可以指定输出转义字符是否无效。默认值是no。指定为on时,

    <xsl:text disable-output-escaping="yes">
      &lt;
    </xsl:text>
    

    的输出为

      <
    

    5.5 生成注释

    需要生成注释时可以使用xsl:comment元素。

    <xsl:commwnt>这里是注释。</xsl:comment>
    

    的输出如下所示。

    <!--这里是注释。-->
    

    5.6 复制

    复制当前节点可以使用xsl:copy元素。属性和子节点不会被自动复制。基本代码如下所示。

    <xsl:copy>
      <!-- 内容:模板 -->
    </xsl:copy>
    

    例如,将没有属性的上下文元素属性原样输出,可以使用如下的模板规则。

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

    若需要递归地复制所有节点,可以使用如下的模板规则。

    <xsl:template match="@*|node()">
      <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
    </xsl:template>
    

    5.7 生成元素

    需要生成元素时可以使用xsl:element元素。通常,只要将需要生成的元素直接写出即可,不必使用xsl:element元素。该元素仅在需要动态生成元素时才有必要使用。基本代码如下所示。

    <xsl:element
      name = "生成元素的名称">
      <!-- 内容: 模板 -->
    </xsl:element>
    

    例如,若要由

    <heading>
      <text>这是标题。</text>
      <size>2</size>
    </heading>
    

    生成HTML标题(h元素),则可以使用如下的模板规则。

    <xsl:template match="heading">
      <xsl:element name="{concat('h', size)}">
        <xsl:value-of select="text"/>
      </xsl:element>
    </xsl:template>
    

    concat()是字符串连接函数。从size元素中取出值并将其连接在“h”之后构成元素名。输出如下所示。

    <h2>这是标题。</h2>
    

    5.8 生成属性

    需要生成属性时可以使用xsl:attribute元素。与生成元素的情况相同,通常只需要将需要生成的属性直接写出即可,不需使用xsl:attribute元素。该元素仅在需要动态生成属性等场合才有必要使用。基本代码如下所示。

    <xsl:attribute
      name = "生成属性的名称">
      <!-- 内容:模板 -->
    </xsl:attribute>
    

    例如3 ,若想由

    <link>
     <title>技术评论公司</title>
     <url>http://www.gihyo.co.jp/</url>
    </link>
    

    生成如下的HTML链接时,

    <a href="http://www.gihyo.co.jp/">
      技術評論社
    </a>
    

    可以定义如下的模板规则。

    <xsl:template match="link">
      <a>
        <xsl:attribute name="href">
          <xsl:value-of select="url"/>
        </xsl:attribute>
        <xsl:value-of select="title"/>
      </a>
      </xsl:template>
    

    5.9 添加编号

    需要输出整数值时可以使用xsl:number元素。基本代码如下所示。

    <xsl:number
      level = "源树的级别"
      count = "表达式"
      from = "表达式"
      value = "数值表达式"
      format = "表示格式的字符串" />
    

    首先看看最简单的例子。

    <items>
      <item>A</item>
      <item>D</item>
      <item>B</item>
      <item>C</item>
    </items>
    

    对该XML文档定义如下的模板规则。

    <xsl:template match="items">
      <xsl:copy>
        <xsl:apply-templates select="item"/>
      </xsl:copy>
    </xsl:template>
    <xsl:template match="item">
      <xsl:copy>
        <xsl:number/>
        <xsl:text> </xsl:text>
        <xsl:value-of select="."/>
      </xsl:copy>
    </xsl:template>
    

    生成结果如下所示。

    <items>
      <item>1 A</item>
      <item>2 D</item>
      <item>3 B</item>
      <item>4 C</item>
    </items>
    

    省略value属性时,则根据源树内当前节点的位置来输出数值。由于这个原因,若使用后面将要讲到的排序元素的话,即如果定义如下所示的模板规则的话,

    <xsl:template match="items">
      <xsl:copy>
        <xsl:for-each select="item">
          <xsl:sort select="."/>
          <xsl:copy>
            <xsl:number/>
            <xsl:text> </xsl:text>
            <xsl:value-of select="."/>
          </xsl:copy>
        </xsl:for-each>
      </xsl:copy>
    </xsl:template>
    

    输出结果将如下所示。

    <items>
      <item>1 A</item>
      <item>3 B</item>
      <item>4 C</item>
      <item>2 D</item>
    </items>
    

    需要按照排序结果的顺序来添加编号的话,则须按照如下方式指定value属性。position()函数返回正在处理的上下文节点的位置。

    <xsl:number value="position()"/>
    

    可以使用level属性、count属性、from属性来控制编号方法。count属性设置应当被编号的节点。level属性设置作为编号对象的源树的级别。可指定的级别有single、multiple、any三种,默认值为single。

    例如,有下面这种层次结构的XML文档。

    <chapter title="第一章">
      <section title="第一节">
        <subsection title="第一部分">
        </subsection>
      </section>
      <section title="第二节">
        <subsection title="第二部分">
        </subsection>
        <subsection title="第三部分">
        </subsection>
      </section>
    </chapter>
    

    将xsl:number元素的level属性设置为single,即将如下的模板规则应用于该文档,

    <xsl:template match="chapter|section|subsection">
      <xsl:apply-templates select="@title"/>
      <xsl:apply-templates select="*"/>
    </xsl:template>
    <xsl:template match="@title">
      <xsl:number level="single"
        count="chapter|section|subsection"/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="."/><br/>
    </xsl:template>
    

    转换结果如下所示。

    1 第一章<br/>
    1 第一节<br/>
    1 第一部分<br/>
    2 第二节<br/>
    1 第二部分<br/>
    2 第三部分<br/>
    

    也就是输出在兄弟节点中当前节点的位置。设置level属性为multiple时,转换结果如下所示。

    1 第一章<br/>
    1.1 第一节<br/>
    1.1.1 第一部分<br/>
    1.2 第二节<br/>
    1.2.1 第二部分<br/>
    1.2.2 第三部分<br/>
    

    编号与single相同,但是增加了父节点的编号。设置level属性为any时,转换结果如下所示。

    1 第一章<br/>
    2 第一节<br/>
    3 第一部分<br/>
    4 第二节<br/>
    5 第二部分<br/>
    6 第三部分<br/>
    

    也就是按照符合count指定的表达式的节点的顺序输出序号。

    from属性设置计数开始的位置。例如,考虑如下的XML文档。从逻辑上看,各个节点之间有父子关系,但是在源树中各个节点是并列关系。

    <h1>大标题一</h1>
    <h2>中标题一</h2>
    <h3>小标题一</h3>
    <h2>中标题二</h2>
    <h3>小标题二</h3>
    <h3>小标题三</h3>
    

    下面使用from属性设置计数开始的节点。

    <xsl:template match="h1">
      <xsl:number/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="."/><br/>
    </xsl:template>
    <xsl:template match="h2">
      <xsl:number level="any" count="h1"/>
      <xsl:text>.</xsl:text>
      <xsl:number level="any" from="h1" count="h2"/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="."/><br/>
    </xsl:template>
    <xsl:template match="h3">
      <xsl:number level="any" count="h1"/>
      <xsl:text>.</xsl:text>
      <xsl:number level="any" from="h1" count="h2"/>
      <xsl:text>.</xsl:text>
      <xsl:number level="any" from="h2" count="h3"/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="."/><br/>
    </xsl:template>
    

    转换结果如下所示。

    1 大标题一<br/>
    1.1 中标题一<br/>
    1.1.1 小标题一<br/>
    1.2 中标题二<br/>
    1.2.1 小标题二<br/>
    1.2.2 小标题三<br/>
    

    使用format属性设置输出文字的格式。默认的格式为“1”,即输出数字。用于表示格式的字符串如表2所示。

    表2: 格式字符串
    字符串 格式范例
    1 1 2 ... 10 11 ...
    01 01 02 ... 09 10 ... 99 100 ...
    A A B ... Z AA AB ...
    a a b ... z aa ab ...
    i i ii iii iv v vii viii ix x ...
    I I II III IV V VII VIII IX X ...

    我们上面的例子中为了在xsl:number元素之后加一个空格,不得不使用了xsl:text元素。实际上只要将format属性设置为“1 ”就可以了。level属性为multiple的情况下也可以指定类似于“1.A.I”这样的格式。

    6 循环

    需要循环进行处理时可以使用xsl:for-each元素。基本代码如下所示。

    <xsl:for-each
      select = "节点集合">
      <!-- 内容:(xsl:sort*, 模板) -->
    </xsl:for-eaxh>
    

    必须设置select属性,来指定被处理的节点集合。如果使用了后面讲述的排序的话则按照排序结果的顺序进行处理,否则按照节点出现顺序进行处理。

    例如,如下所示,bookmark元素中包含了多个link元素。

    <bookmark>
      <link>
        <title>技术评论公司</title>
        <url>http://www.gihyo.co.jp</url>
      </link>
      <link>
        <title>ONGS</title>
        <url>http://www.ongs.gr.jp</url>
      </link>
    </bookmark>
    

    利用下面使用了xsl:for-each元素的模板规则,可以将其转换成HTML表格(图1)。

    <xsl:template match="bookmark">
      <table border="1"> 
        <xsl:for-each select="link">
          <tr> 
            <td><xsl:value-of select="title"/></td>
            <td><xsl:value-of select="url"/></td>
          </tr>
        </xsl:for-each>
      </table>
    </xsl:template>
    
    图1: 使用表格进行显示

    但是,使用如下所示的模板规则,不用xsl:for-each元素也能得到同样的输出结果。

    <xsl:template match="bookmark">
      <table border="1"> 
        <xsl:apply-templates select="link"/>
      </table>
    </xsl:template>
    <xsl:template match="link">
       <tr>
         <td><xsl:value-of select="title"/></td>
         <td><xsl:value-of select="url"/></td>
       </tr>
    </xsl:template>
    

    仅定义模板规则有时候很难进行转换。例如,需要将行和列交换生成如图2所示的表时,不使用xsl:for-each元素就很难做到。

    图2: 行列交换

    使用xsl:for-each元素可以生成如图2所示的输出结果。

    <xsl:template match="bookmark">
      <table border="1"> 
        <tr> 
          <xsl:for-each select="link/title">
            <td><xsl:value-of select="."/></td>
          </xsl:for-each>
        </tr>
        <tr> 
          <xsl:for-each select="link/url">
            <td><xsl:value-of select="."/></td>
          </xsl:for-each>
        </tr>
      </table>
    </xsl:template>
    

    7 条件处理

    在XSLT中,进行条件处理的元素有xsl:if和xsl:choose两个。xsl:if进行“如果~就~”的if-then型处理,xsl:choose当有多个选择项存在时进行处理。

    7.1 xsl:if

    xsl:if元素拥有test属性,可指定逻辑表达式。逻辑表达式为真的情况下执行模板的转换,假的情况下不进行转换。

    <xsl:if
      test = "逻辑表达式">
      <!-- 内容: 模板 -->
    </xsl:if>
    
    例如,对以下XML文档,
    <people>
      <person>
        <name>张三</name>
        <age>30</age>
      </person>
      <person>
        <name>李四</name>
        <age>20</age>
      </person>
      <person>
        <name>周五</name>
        <age>10</age>
      </person>
    </people>
    

    使用如下所示的模板进行变换。

    <xsl:template match="people">
      <ul>
        <xsl:apply-templates select="person"/>
      </ul>
    </xsl:template>
    <xsl:template match="person">
      <li>
        <xsl:value-of select="name"/>今年
        <xsl:value-of select="age"/>岁
        <xsl:if test="age[.&lt; 18]">
          (未成年)
        </xsl:if>
      </li>
    </xsl:template>
    

    &lt;是<的意思(&gt;是>)。age元素的值不足18的情况下输出“(未成年)”。输出结果如下所示。

    <ul>
      <li>张三今年30岁</li>
      <li>李四今年20岁</li>
      <li>周五今年10岁(未成年)</li>
    </ul>
    

    7.2 xsl:choose

    xsl:choose元素由一个或一个以上的xsl:when元素和可选的xsl:otherwise元素组成。

    <xsl:choose>
      <xsl:when test="逻辑表达式">
        <!-- 内容: 模板 -->
      </xsl:when>
      <xsl:otherwise>
        <!-- 内容: 模板 -->
      </xsl:otherwise>
    </xsl:choose>
    

    与xsl:if元素相同,test属性的逻辑表达式为真的情况下执行指定的模板。从上到下依次测试xsl:when元素,但只有第一个逻辑表达式为真的xsl:when院所的模板会被执行。如果所有的xsl:when元素的逻辑表达式均为假,则执行xsl:otherwise元素所指定的模板。xsl:otherwise元素不存在时则不执行任何模板。

    例如,对于如下文档,

    <ol>
      <li>起床</li>
      <li>洗脸</li>
      <li>吃早饭</li>
      <li>上班</li>
    </ol>
    

    应用如下所示的模板。last()函数返回被处理的内容的大小。

      <xsl:template match="ol">
        <morning>
          <xsl:for-each select="li">
            <todo>
              <xsl:choose>
                <xsl:when test="position()=1">
                  <xsl:text>首先</xsl:text>
                </xsl:when>
                <xsl:when test="position()=last()">
                  <xsl:text>最后</xsl:text>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:text>第</xsl:text>
    			   <xsl:value-of select="position()"/>
                </xsl:otherwise>
              </xsl:choose>
              <xsl:value-of select="."/>
            </todo>
          </xsl:for-each>
        </morning>
      </xsl:template>
    

    输出结果如下所示。

      <morning>
        <todo>首先起床</todo>
        <todo>第2洗脸</todo>
        <todo>第3吃早饭</todo>
        <todo>最后上班</todo>
      </morning>
    

    8 排序

    为将数据排序,可以在xsl:apply-templates元素或xsl:for-each元素的子节点中增加xsl:sort元素。xsl:sort元素的基本代码如下所示。

    <xsl:sort
      select = "字符串表达式"
      data-type = "数据类型"
      order = "顺序"/>
    

    通过select属性指定排序的节点。通过data-type属性指定字符串的数据类型。设置为text就能够按照人们默认的字典顺序进行排序。设置为number将把字符串看作数字,按照数字的值进行排序。order属性设置排序的顺序。升序为ascending、降序为descending。未指定时默认为升序。其他能够设置的属性包括设置语言的lang属性,设置大小写字母哪个优先的case-order属性等。

    例如,将如下所示的由姓名(name)、年龄(age)组成的人(person)的数据按照姓名和年龄进行排序。

    <people>
      <person>
        <name>张三</name>
        <age>30</age>
      </person>
      <person>
        <name>李四</name>
        <age>20</age>
      </person>
      <person>
        <name>周五</name>
        <age>10</age>
      </person>
    </people>
    

    下面是按照年龄升序、姓名降序进行排序并生成HTML表格的模板规则。

    <xsl:template match="people">
      <h1>按照年龄升序排列</h1>
      <table border="1">
        <xsl:apply-templates select="person">
          <xsl:sort select="age"
                    data-type="number"/>
        </xsl:apply-templates>
      </table>
      <h1>按照姓名降序排列</h1>
      <table border="1">
        <xsl:apply-templates select="person">
          <xsl:sort select="name" data-type="text" order="descending"/>
        </xsl:apply-templates>
      </table>
    </xsl:template>
    <xsl:template match="person">
      <tr>
        <td><xsl:value-of select="name"/></td>
        <td><xsl:value-of select="age"/></td>
      </tr>
    </xsl:template>
    

    输出结果如图3所示。

    图3: 排序结果

    与此相同,使用xsl:for-each元素重新书写代码则如下所示。要注意,在将xsl:sort元素作为xsl:for-each元素的子节点使用时,必须将其写在开头的地方。

    <xsl:template match="people">
      <h1>按照年龄降序排列</h1>
      <table border="1">
        <xsl:for-each select="person">
          <xsl:sort select="age" data-type="number"/>
          <tr>
            <td><xsl:value-of select="name"/></td>
            <td><xsl:value-of select="age"/></td>
          </tr>
        </xsl:for-each>
      </table>
      <h1>排序</h1>
      <table border="1">
        <xsl:for-each select="person">
          <xsl:sort select="name" data-type="text" order="descending"/>
          <tr>
            <td><xsl:value-of select="name"/></td>
            <td><xsl:value-of select="age"/></td>
          </tr>        
        </xsl:for-each>
      </table>
    </xsl:template>
    

    9 变量

    在XSLT中可以使用变量。

    9.1 绑定变量

    可以为变量赋值的元素有xsl:variable元素和xsl:param元素。

    9.1.1 xsl:variable元素

    基本代码如下所示。

    <xsl:variable
      name = "变量名"
      select = "表达式">
      <!-- 内容: 模板 -->
    </xsl:variable>
    

    使用name属性指定变量名(必须)。select属性和内容都不存在的话可以写成空字符串。

    <xsl:variable name="x"/>
    

    这种写法与下面的写法意思相同。

    <xsl:variable name="x" select="''"/>
    

    通过select属性可以指定变量中代入的值。使用select属性给变量赋值的话,内容必须为空。例如给变量x赋值为2时的代码如下所示。

    <xsl:variable name="x" select="2"/>
    

    这种情况下,使用

    <xsl:value-of select="item[$x]"/>
    

    将输出第二个item元素。

    通过内容来赋值时,变量的值不是数值,而是结果树的片断。关于结果树的片断请参照参考文献[1]。

    <xsl:variable name="x">2</xsl:variable>
    

    这种情况下,使用

    <xsl:value-of select="item[$x]"/>
    

    不会输出第二个item元素,而是输出了第一个元素。使用值为结果树片断的变量时应当像下面这样书写代码。

    <xsl:value-of select="item[position()=$x]"/>
    

    9.1.2 xsl:param元素

    xsl:variable元素和xsl:param元素基本上相同。一个区别是,XML解释器假定xsl:param变量中保存着默认值,并可以使用xsl:with-param元素来向模板中传值。详细情况请参见参考文献[1]。

    9.2 访问变量

    在表达式中访问变量时,需要在变量名前加上$符号。使用xsl:value-of元素访问变量则可以输出变量的值。

    10 指定输出格式

    XSLT处理器的任务是从XML文档转换成新的XML文档,但是也能够输出XML文档之外的格式。通过xsl:output元素可以指定输出格式。该元素只能作为顶层元素使用。基本代码如下所示。

    <xsl:output 
      method = "输出格式"
      version = "版本" 
      encoding = "编码"
      omit-xml-declaration = "yes" | "no"
      standalone = "yes" | "no"
      indent = "yes" | "no" />
    

    通过method指定输出格式。可以指定的格式包括html、html、text等。未指定时默认为xml,但如果满足以下条件则为html。

    • 结果树的根节点的元素名为html(不区分大小写),并且含有子元素。
    • 不包含命名空间的URI。
    • 结果树的根节点的子元素之前出现的文本只包含空白。

    通过version可以指定输出格式的版本。通过encoding指定输出时使用的字符编码。通过omit-xml-declaration来指定是否省略XML定义。通过standalone指定是否输出独立文档的声明。通过indent指定输出结果树时是否使用缩进的格式。

    例如,输出i-mode能够浏览的HTML时,可以如下书写代码。由于i-mode只能使用Shift_JIS编码,因此需要按下面的方式定义。

    <xsl:output method="html" encoding="Shift_JIS" indent="no"/>
    
  • 相关阅读:
    android 中管理短信
    Note: log switch off, only log_main and log_events will have logs!
    Android中内容观察者的使用---- ContentObserver类详解 (转)
    Mac下eclipse安装SVN插件
    手把手教你在Eclipse中使用CVS Branch功能
    DIV+CSS命名规范-转载2
    DIV+CSS命名规范-转载1
    仓库入仓-手机条码扫描
    速卖通承认的承运商代码
    同一个仓库,供应商和分销商的库存同时存在的问题
  • 原文地址:https://www.cnblogs.com/Dicky/p/135257.html
Copyright © 2011-2022 走看看