6.3 XSLT 样式单的元素和指令

###6.3 XSLT样式单的元素和指令

  • <xsl:stylesheet>元素

  • 每个完整的XSLT样式单都有一个xsl:stylesheet或xsl:transform元素作为其文档元素

    • <xsl:stylesheet><xsl:transform>语义上等同,可互换使用

    • 某些非常简单的XSLT样式单可能没有xsl:stylesheet,但可存在一个HTML文档里面分散包含来自XSLT命名空间的元素

    • xsl:stylesheet开始标签必须有一个version属性(位置)

      • 现在常用1.0

    • 必须有一个命名空间声明

      • 命名空间声明中的其他URL表示非XSLT命名空间中的元素

      • XSLT命名空间前缀:xslt/xsl或其他

  • <xsl:template>元素

  • XSLT处理器在样式表中查找一个match属性值为/的xsl:template元素(根节点)

  • 搜索到根节点时就根据模板内容,在目标树中增加一个与模板内容相对应的树形结构

    • 只有一个根节点,则只允许根节点在目标树中添加一次

    • 模板中与根节点匹配的元素大都是HTML或XHTML元素

      • 字面结果元素(Literal Result Elements)

    • 模板中来自XSLT命名空间的元素被称为指令(Instructions)

  • 模板是XSLT转换工作的具体规则,所有的转换任务是通过一系列的模板体现出来的。因此,如何声明和调用模板,是XSLT转换任务的关键

  • 在XSLT文档中通常至少包含一个模板,即xsl:templatematch=“/”,该模板用于处理文档节点(Document Node),相当于程序设计语言中的main()函数

  • 模板在很多方面都与函数非常类似,必须首先声明(可以指定模板的名称、参数、返回类型等),然后在合适的地方显式地调用(在遍历文档树节点的过程中或直接调用),才能够执行相应的转换规则

  • 完整的模板声明语法

  • <xsl:template></xsl:template>之间的内容相当于一个函数的函数体,表示在调用该模板时应执行的具体操作。而xsl:template元素开始标记中的属性(match, name, mode和priority)用于描述该模板的相关信息

  • match属性的取值涉及到模板的调用,分两种方式

    • 根据模板的匹配路径(在遍历的过程中)进行调用,具体有两种情况

      • 对于模板xsl:templatematch=“/“,XSLT处理器将在碰到XML文档的文档节点时自动调用该模板,类似程序执行的入口,Java 虚拟机自动调用主类的main()方法

      • 对于其他的模板match=other-pattern,将在模板xsl:templatematch="/“的转换规则(函数体)中通过指出匹配路径的方式(使用xsl:apply-templates)进行隐式或者显式地调用

    • 根据模板名称属性(name),使用xsl:call-templatename=template-name进行调用

  • match属性值可以使用绝对路径表达式(比如“/message”),这表示在遍历文档树的过程中碰到/message元素时,需要执行该模板中的内容;如果使用相对路径表达式,模板2将应用于/message、/*/message 等(所有含message的元素)

  • 模板<xsl:templatematch=“/”><xsl:templatematch=“message”>都没有具体的名称,称为无名模板

  • 这些模板之所以可以没有名称,是因为它们的调用是在遍历文档树的过程中自动进行的,根本不需要名称

  • 也可以使用name属性为模板指定一个名称,使其成为命名模板

:` < output

Simple output </ output>`

  • 对于一个模板来说,可以同时使用match和name属性,以便能够在遍历过程中根据路径匹配情况自动地调用,或者使用xsl:call-template直接调用

  • 模板的mode属性可用于对模板进行进一步的标识

  • priority属性是用来表示模板的优先级

  • 碰到Name元素时将使用priority取值较大的模板

  • 模板返回类型属性as的取值,表示该模板应该返回的数据类型

  • 表示该模板将会返回一个XML元素作为结果,其中可能包含子元素和文本内容。如果该模板输出多个XML元素组成的序列、非XML元素内容或者文本内容,则XSLT处理器在执行模板的过程中将会报错

  • as是一个可选的参数,如果不指定该参数,则模板可以输出任意的文本内容

  • <xsl:apply-templates>元素

  • 与根节点对应的模板中有一个名为xsl:apply-templates的元素

    • 促使XSLT处理器根据select属性(可选)指定要处理的节点集

      • 省略则表示处理元素子节点

      • 可实现对模板的递归引用

    • 模板内容的一部分由LRE组成,一部分由XSLT命名空间元素(xsl:value-of元素)组成

  • 模板的调用

    • 在遍历(广度优先遍历)的过程中匹配调用

    • 通过名称直接调用

  • 使用xsl:apply-templates在广度优先、逐层向下的遍历过程中调用模板

    • XSLT中apply-templates元素的完整语法形式如下

  • select和mode属性都是可选的在xsl:apply-templates元素中可以传递调用参数

  • select属性

    • xsl:apply-templates的作用就是指定继续遍历当前节点的所有子节点(以便根据实际路径和模板的match属性取值调用对应的模板),而select属性(取值为一个XPath表达式)允许指定仅遍历当前节点的哪些子节点(以调用相应的模板,如果存在)

    • 如果将上述源码的模板1中的xsl:apply-templates/更改为xsl:apply-templatesselect="message"/,那么将仅调用message元素所对应的模板(而不会调用处理指令所对应的模板)。这样就可以根据具体的转换要求,仅遍历文档树中的部分内容

  • mode属性可实现某个节点多次处理的需要

    • 当xsl:apply-templates有一个mode属性时,只有当match和mode两个属性值都有匹配值时,其模板才可实例化

    • mode属性用于指定需要在match属性取值相同的模板中选择哪一个进行调用

    • 需要与xsl:template元素的mode属性配合使用

  • mode属性可实现某个节点多次处理的需要

  • 可以为模板3和模板4的match属性取不同的值

  • <xsl:variable><xsl:param>元素

  • 定义变量和参数

  • 引用变量和参数使用$

  • 参数可以从外部传递给转换程序,变量则在XSLT样式表内部定义

  • 变量赋值 <xsl:paramname=”searchLetter” select=”’A’”/>

    • 使用xsl:variable的select属性 <xsl:variablename=” variableName” select=” someExpression” />

    • 在xsl:variable元素的起始标签和结束标签之间定义

  • 命名模板和<xsl:call-template>元素

  • 命名模板由xsl:template元素的name属性标识

  • 调用命名模板使用xsl:call-template元素 <xsl:call-templatename=”TemplateName” />

    • 不带任何参数调用命名模板

  • xsl:with-param元素用于在使用xsl:template声明模板时声明参数,也用于在xsl:call-template或者xsl:apply-templates中传递调用参数

    • xsl:with-param的select属性可选,其值为表达式,表示如何选取需要传递的值

  • 模板参数的声明和传值

  • 在xsl:template元素开始标记和结束标记之间,使用xsl:param元素为所在的模板声明相应的模板参数

  • 在xsl:call-template元素的开始标记和结束标记之间,可以使用xsl:with-param元素为所调用的模板传递所需的参数

  • XSLT中的内置模板

  • 内置模板(Built-in Templates)是XSLT中的一个关键内容,对于理解XSLT对XML文档树结构的遍历方式、模板调用机制等都是至关重要的

  • 通过一个具体的示例来说明内置模板的存在,并观察和解释各种内置模板的含义、以及处理对象

  • 内置模板的作用在于能够让我们集中精力编写相关节点的处理模板,而无需过多地操心整个遍历过程中模板的逐层调用

  • 只有在用户没有自定义处理某个节点的模块规则时,才会调用内置模块中的规则,否则,用户自定义的模块规则将覆盖内置模块中的规则

  • <xsl:value-of>元素

  • 提供源树中某一部分的值

    • 必须有一个select属性表明定位路径

    • 模板内容的一部分由LRE组成,一部分由XSLT命名空间元素(xsl:value-of元素)组成

  • 上下文节点(Context Node)

    • 上下文是指当前处理器正在处理的节点的位置,该节点称为上下文节点

    • 上下文不只包括上下文节点,也包括上下文位置、上下文大小等

  • 可获得XML文档结构树中所有节点的值 |节点类型|节点值| |-|-| |根节点|用“/”匹配,通常不直接求节点值| |指令|用processing-instruction()匹配,值不包含值令名称、<?和?>| |注释|用comment()匹配,值不包含<?--和-->| |元素|可用多种方式匹配,值为元素本身以及元素内容| |元素属性|用@属性名匹配,值为属性值,不含双引导| |元素内容|用text()匹配,元素本身包含的文本内容|

  • 节点选择方式

  • <xsl:template>的match属性用于指定要匹配的节点

  • <xsl:copy-of>, <xsl:for-each>, <xsl:sort>, <xsl:apply-template><xsl:value-of>的select属性用于选择节点

  • <xsl:copy>元素

  • 把一个节点复制到目标树,但不复制子孙节点

  • 如果上下文节点是一个元素节点,则不会复制节点的任何属性值

    • 使用某个元素并可改变其内容或增删属性

  • 只处理xsl:copy

  • 使用xsl:attribute增加属性

  • 深度复制,把一个节点及其所有属性节点和子孙节点都复制到目标树 ||xsl:copy|xsl:copy-of| |-|-|-| |功能|将当前节点从源文档复制到目标树|复制任何节点集到目标树| |对当前节点的处理|仅复制当前节点,不复制其子元素或者属性|复制节点及其所有的子孙节点,包括属性和子元素| |节点内容|可以使用XSLT代码为新的节点创建内容,如果当前节点是元素节点或者根节点|所有的内容都来自select属性中指定的节点集|

  • <xsl:output>元素

  • 使用method属性从XML, HTML或文本文档中选择一种输出格式

    • method属性的值大小写敏感,并且必须小写(xml, html, text)

<xsl:output method=“output type” />

  • <xsl:if>元素

  • 测试一个布尔条件

    • 为真则实例化<xsl:if>元素的内容

    • 为假则<xsl:if>元素的内容不会被添加到目标树

    • 输出一些内容或没有任何输出

  • test属性返回false时,Character元素的模板不输出任何内容

  • <xsl:choose>元素

  • 多个选项中选取一个

    • xsl:choose可以有任意个xsl:when元素作为其子元素,每一个都有一个test属性进行逻辑判断

    • 如果xsl:when元素内容均未输出,则输出xsl:otherwise元素内容

  • <xsl:for-each>元素

  • 把嵌入其中的XSLT指令作用到节点集的每个元素

  • 可迭代处理整个节点集,并为节点集中每个节点生成输出文档

    • 理论上处理器可按任意顺序处理节点集中的节点

用LRE表示无序列表的起始标签和结束标签(<ul></ul>),上下文节点是Object元素节点,xsl:for-each为上下文节点的每个子节点生成一个列表项,列表项对应于上下文节点的每个Characteristic元素

  • <xsl:sort>元素

  • 可对节点集中的元素排序,可多次使用

    • 元素在输出中的顺序可完全不同于节点在源文档中的顺序

  • 可与xsl:apply-templates和xsl:for-each一起使用

  • xsl:sort的select属性值是一个相对定位路径@name,是Object的子节点name属性节点

  • xsl:sort的order属性来说明排序模式,默认排序为升序

  • <xsl:include><xsl:import>元素

  • 都是xsl:stylesheet的直接子元素

  • xsl:include将外部的样式单复制到该元素所在位置,一个样式单只能被包含一次,被包含样式单的模板规则与包含者规则优先级相同

  • xsl:import和xsl:include的区别

  • import与include必须为顶层元素,如果import与include同时存在,那么import在include之前声明

  • include与原样式表中的模板处于完全相同的地位(具有相同的默认优先级),没有任何差别,但是import导入的模板则具有较低的默认优先级

  • importadds components from another schema with a different namespace nnincludeassociates with the target namespace

Last updated