XSLT快速参考

XSLT快速参考

1 前言

在计算机科学中,XSLT是扩展样式表转换语言(Extensible Stylesheet Language Transformations)的简称,这是一种对XML文档进行转化的语言,XSLT中的T代表英语中的“转换”(transformation)。它是XSL(Extensiblestylesheetlanguage)规范的一部分。

XSLT是一种用于将XML文档转换为文档或其他XML文档的语言。 也可以转换成非xml文档,如txt,html, java等等其他文档

XPath是一种用于在XML文档中进行导航的语言。

XSLT指XSL转换(XSLTransformations)。

XSLT是XSL中最重要的部分。

XSLT可将一种XML文档转换为另外一种XML文档。

XSLT使用在XML文档中进行导航。

XPath是一个标准。

XSLT=XSL转换。

我们用一个简单的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: 常用的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 属性值模板

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

例如,想由   <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>   例如 ,若想由   <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: 格式字符串

字符串格式范例
11 2 ... 10 11 ...
0101 02 ... 09 10 ... 99 100 ...
AA B ... Z AA AB ...
aa b ... z aa ab ...
ii ii iii iv v vii viii ix x ...
II 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>

www.zeeklog.com  - XSLT快速参考

图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元素就很难做到。

www.zeeklog.com  - XSLT快速参考

图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所示。

www.zeeklog.com  - XSLT快速参考

图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"/>

Read more

手把手教你干掉if else

手把手教你干掉if else

今天想来跟大家讨论一下怎么干掉if else。 已经工作的人可能深有体会:没有什么是if else搞不掂的,如果有,那就再嵌套一层。 大多数人都是做业务开发的,if else是避免不了的,但怎么让if else的逻辑看起来更顺眼,变得更加好看,更加好维护呢? 如果之前看过三歪文章的同学可能就会想到「责任链模式」。 没错就是 当你看到一个Service中有一大堆if else 逻辑的时候,可能你会幻想着要不要重构掉,但是始终下不了手。 所以,今天想来分享一个「通用」的责任链模式的模板,把if else给套进去就完事了,我相信都能学会。 之前写设计模式文章的时候,有的同学会评论说我把东西搞复杂了,本来就有简单的方式去弄,为啥就要嵌套这么多层去搞这些花里胡哨的东西。 在我看来,用最简单的方式去实现是没有任何问题的。但达到一定代码量的时候,多想想一下,换一个人去维护,人家能不能看懂,有没有更加好的方式,这往往就需要「抽象」的能力。 这也是为什么这么多人推崇设计模式的原因。 不多BB,来吧。 责任链通用实现 现在我就默认大家都知道什么是责任链模式了,如果还对这个不懂的同

By Ne0inhk
最近学到的Lambda表达式基础知识

最近学到的Lambda表达式基础知识

前言    外滩 学了一下Java的函数式编程,给大家整理了一下,一起学习! 一、Lambda用法 之前写Optional这个类的时候,简单说了一下Lambda是怎么用的,这里再跟大家一起回顾一下,Lambda的语法是这样的: 语法 以Lambda语法创建线程和匿名内部类创建线程的区别(显然代码少了很多!): public static void main(String[] args) {     // 用匿名内部类的方式来创建线程     new Thread(new Runnable() {         @Override         public void run() {             System.out.println("公众号:Java3y---关注我!");         }     });     // 使用Lambda来创建线程     new Thread(() -> System.out.println("公众号:Java3y---关注我!")); } 使用Lambda表达式,实际就是创建出该接口的实例对象。

By Ne0inhk
手把手带你体验Stream流

手把手带你体验Stream流

前言 上一篇讲解到了Lambda表达式的使用《》,还没看的同学可以先去阅读一下哈~ 相信也有不少的同学想要知道:Lambda表达式在工作中哪个场景会用得比较多?跟Lambda搭边的,使用Stream流会比较多 一般人第一次看Stream流的代码,都会有点看不懂(它的代码看起来好像就不是写Java一样.),希望这篇文章能带大家入个门 一、体验Stream流 大家在自学时,大多数会学过一个程序:算出从数组元素的和,当时我们是怎么写的?一般来说是这样的: public static void main(String[] args) {     int[] nums = { 1, 2, 3 };     int sum = 0;     for (int i : nums) {         sum += i;     }     System.out.println("结果为:" + sum); } 如果我们使用Stream流的话,可以这样: public static void

By Ne0inhk
【JVM】关于JVM,你需要掌握这些!!

【JVM】关于JVM,你需要掌握这些!!

写在前面 经过十几天的收集与整理,初版算是整理出来了。希望对大家有所帮助。 JDK 是什么? JDK 是用于支持 Java 程序开发的最小环境。 1. Java 程序设计语言 2. Java 虚拟机 3. Java API类库 JRE 是什么? JRE 是支持 Java 程序运行的标准环境。 1. Java SE API 子集 2. Java 虚拟机 Java历史版本的特性? Java Version SE 5.0 * 引入泛型; * 增强循环,可以使用迭代方式; * 自动装箱与自动拆箱; * 类型安全的枚举; * 可变参数; * 静态引入; * 元数据(注解); * 引入Instrumentation。 Java

By Ne0inhk