XSLT 1.0推荐标准摘译(第三部分)

 

6 命名模板

<!-- Category: instruction -->
<xsl:call-template  name = qname>
  <!-- Content:
xsl:with-param * -->
</xsl:call-template>

模板规则可以按名称调用,模板规则的名称用name 属性指定,指定name 属性的模板规则可以不指定match 属性。Xsl:all-template 用于按名称调用模板规则,与xsl:apply-templates 不同的是,xsl:call-template 不改变当前节点或当前节点列表。Matchmodepriority 属性不影响模板调用。

 

7 创建结果树

7.1 创建元素和属性

7.1.1 字面结果元素

样式表中不属于XSLT 名称空间,也不是扩展元素的元素,在实例化的时候将创建同名的元素节点。元素的内容是一个模板,实例化的时候将生成该元素的内容。样式表树中不属于XSLT 名称空间的那些属性节点将复制到结果树中。

样式表树元素节点中名称空间节点将被复制,但是不包括XSLT 名称空间、扩展名称空间或者指定排除的名称空间。排除名称空间可以在xsl:stylesheet 元素中使用exclude-result-prefixes ,或者在字面结果元素中使用xsl:exclude-result-prefixes 。这两个属性的值都是用空白分隔的名称空间前缀列表。排除默认名称空间(声明为xmlns )可使用#default 来排除。

字面结果元素的属性值作为属性值模板处理,可以用{} 包含表达式。样式表树中用于指定结果树名称空间URI 的名称空间URI 称为字面名称空间URI ,可用于指定字面结果元素扩展名中的名称空间URI 、字面结果元素属性扩展名中的名称空间URI 、字面结果元素名称空间节点的字符串值。

<!-- Category: top-level-element -->
<xsl:namespace-alias
stylesheet-prefix = prefix | "#default" result-prefix = prefix | "#default" />

xsl:namespace-alias 元素用于声明名称空间URI 的别名,出现在结果树中的URI 将是它所指代的那个URI 。绑定到 stylesheet-prefix 属性所指定前缀的URI ,是绑定到result-prefix 前缀的URI 的别名,即stylesheet-prefix 所指URI 出现在样式表中,而result-prefix 所指URI 出现在结果树中。如果使用字面结果元素创建使用XSLT 名称空间的元素、属性和名称空间节点,样式表必须使用别名。比如:

<xsl:stylesheet

  version="1.0"

  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

  xmlns:fo="http://www.w3.org/1999/XSL/Format"

  xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias">

 

<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>

 

<xsl:template match="/">

  <axsl:stylesheet>

    <xsl:apply-templates/>

  </axsl:stylesheet>

</xsl:template>

 

<xsl:template match="block">

  <axsl:template match="{.}">

     <fo:block><axsl:apply-templates/></fo:block>

  </axsl:template>

</xsl:template>

 

</xsl:stylesheet>

换句话说,该元素用于生成XSLT 样式表。(当然可能还有其他情形)

 

7.1.2 使用 xsl:element 创建元素

<!-- Category: instruction -->
<xsl:element
  name = { qname }
  namespace = { uri-reference }
  use-attribute-sets = qnames>
  <!-- Content: template -->
</xsl:element>

xsl:element 用于在结果树中创建元素,元素名可通过计算得到。xsl:element 的内容是一个模板,用于生成新建元素的属性和内容。Name 属性作为属性值模板处理,结果必须是QName

可选属性namespace 也作为属性值模板处理。

 

7.1.3 使用 xsl:attribute 创建属性

<!-- Category: instruction -->
<xsl:attribute
  name = { qname }
  namespace = { uri-reference }>
  <!-- Content: template -->
</xsl:attribute>

xsl:attribute 用于向字面结果元素或者xsl:element 创建的结果元素中添加属性。该元素的内容是一个模板,用于提供新建属性的值。Namenamespace 属性都作为属性值模板处理。

属性必须在任何孩子元素之前添加

属性只能向元素节点添加

Xsl:attribute 元素的内容实例化过程中只能创建文本节点(属性值)

Xsl:attribute 中的文本节点如果包含换行,结果中应包含字符引用,如

<xsl:attribute name="a">x

y</xsl:attribute>

将得到a="x&#xA;y" 而不是

a="x

y"

这是因为XML 1.0 要求属性值中的新行字符规范化为空白,但是不要求新行字符的字符引用进行规范化处理。

 

7.1.4 命名属性集

<!-- Category: top-level-element -->
<xsl:attribute-set
  name = qname
  use-attribute-sets = qnames>
  <!-- Content:
xsl:attribute * -->
</xsl:attribute-set>

xsl:attribute-set 元素定义了一组属性并赋给它一个名称。Name 属性提供属性集的名称,其内容由多个xsl:attribute 元素组成。属性集通过use-attribute-sets 属性来引用,可用于xsl:elementxsl:copy7.5 )或xsl:attribute-set 元素。use-attribute-sets 属性值包括一系列空白分隔的属性集名称。它提供了集中描述一组公共属性的手段。

字面结果元素可通过xsl:use-attribute-sets 属性来引用属性集。顺序如下:首先添加来自xsl:use-attribute-sets 属性集中的属性,其次添加字面结果元素中指定的属性,最后添加xsl:attribute 元素添加的属性。由于添加属性会替代已有的同名属性,因此可用字面结果元素自身指定的属性来覆盖属性集所指定的属性。

每次引用属性集时,xsl:attribute-set 元素中每个xsl:attribute 元素的模板都将被实例化,使用引用该属性集的元素实例化的当前节点和当前节点列表。但决定变量绑定可见性的xsl:attribute 在样式表中的位置,和引用属性集的元素无关,因此只有顶层xsl:variablexsl:param 元素生命的变量和参数是可见的。

下例创建了命名属性集title-style ,然后在模板规则中引用:

<xsl:template match="chapter/heading">

  <fo:block quadding="start" xsl:use-attribute-sets="title-style">

    <xsl:apply-templates/>

  </fo:block>

</xsl:template>

 

<xsl:attribute-set name="title-style">

  <xsl:attribute name="font-size">12pt</xsl:attribute>

  <xsl:attribute name="font-weight">bold</xsl:attribute>

</xsl:attribute-set>

相同扩展名的多个属性集定义将被合并,导入优先级高的属性覆盖优先级低的同名属性。

 

7.2 创建文本

模板中也可包含文本节点,模板中的每个文本节点(去除之后)将在结果树中创建相同串值的文本节点。结果树中相邻的文本节点自动合并。

文本是在树一级处理。因此,模板中的标记&lt; 在样式表树中将被替换为文本节点< 。同样,结果树中也将生成包含< 的文本节点,序列化为XML 文档的时候又转化为标记&lt; (除非取消转义,16.4 )。

<!-- Category: instruction -->
<xsl:text
  disable-output-escaping = "yes" | "no">
  <!-- Content: #PCDATA -->
</xsl:text>

此外还可以用xsl:text 元素包装,包装可能改变空白字符的去除,但此后对XSLT 处理器没有任何作用。XSLT 不对xml:langxml:space 属性处理,是否使用这些属性有作者决定。

 

7.3 创建处理指令

<!-- Category: instruction -->
<xsl:processing-instruction
  name = { ncname }>
  <!-- Content: template -->
</xsl:processing-instruction>

xsl:processing-instruction 元素的内容模板生成处理指令节点的字符串值(类似属性的内容),name 属性指定处理指令的名称。比如:

<xsl:processing-instruction name="xml-stylesheet">href="book.css" type="text/css"</xsl:processing-instruction>

将创建处理指令: <?xml-stylesheet href="book.css" type="text/css"?>

Name 属性值模板实例化后必须是NCName 或者PITarget ,因此不能用xsl:processing-instruction 生成XML 声明,而要使用xsl:outputXsl:processing-instruction 的内容实例化后必须是文本节点,而且不能包含?>

 

7.4 创建注释

<!-- Category: instruction -->
<xsl:comment>
  <!-- Content: template -->
</xsl:comment>

比如: <xsl:comment>This file is automatically generated. Do not edit!</xsl:comment> 将生成注释:

<!--This file is automatically generated. Do not edit!-->

注释内容中不能包含-- ,也不能以- 结束。

 

7.5 复制

<!-- Category: instruction -->
<xsl:copy
  use-attribute-sets = qnames>
  <!-- Content: template -->
</xsl:copy>

xsl:copy 元素提供了复制当前元素的一种简便手段。实例化xsl:copy 元素将创建当前节点的副本,包括名称空间节点,但不包括属性和孩子。xsl:copy 元素的内容用于新建节点的属性和孩子模板(因此只能是元素节点)。

xsl:copy 元素可以引用use-attribute-sets attribute 属性,同样只能在复制元素节点的时候使用。由于结果树的根节点是隐含创建的,因此如果当前节点是根节点,xsml:copy 不会创建根节点,但使用内容模板。比如可用下面的模板规则进行恒等转换:

<xsl:template match="@*|node()">

  <xsl:copy>

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

  </xsl:copy>

</xsl:template>

下面的例子显示了如何复制xml:lang 属性。假设样式表定义了命名模板:

<xsl:template name="apply-templates-copy-lang">

  <xsl:for-each select="@xml:lang">

   <xsl:copy/>

  </xsl:for-each>

  <xsl:apply-templates/>

</xsl:template>

则需要复制xml:lang 属性的时候使用 <xsl:call-template name="apply-templates-copy-lang"/> 即可。

 

7.6 通过计算生成文本

模板中可利用xsl:value-of 计算生成文本,比如从源树中提取文本或者插入变量的值。

7.6.1 使用 xsl:value-of 生成文本

<!-- Category: instruction -->
<xsl:value-of
  select = string-expression
  disable-output-escaping = "yes" | "no" />

xsl:value-of 元素实例化将在结果树中生成一个文本节点。属性select 是一个表达式,求值的结果被转化成字符串。如果生成的是空串则不创建文本节点。相邻的文本节点将自动合并。

与此相对应, xsl:copy-of 元素将把一个节点集复制到结果树中而不转化成字符串。

假设person 元素中包含given-namefamily-name 属性,下面的模板规则将生成一个HTML 片段,包含当前person 节点的这些属性值(注意空格)。

<xsl:template match="person">

  <p>

   <xsl:value-of select="@given-name"/>

   <xsl:text> </xsl:text>

   <xsl:value-of select="@family-name"/>

  </p>

</xsl:template>

类似的,如果上述属性改为孩子元素,则使用下面的模板规则。

<xsl:template match="person">

  <p>

   <xsl:value-of select="given-name"/>

   <xsl:text> </xsl:text>

   <xsl:value-of select="family-name"/>

  </p>

</xsl:template>

下例中假设过程的保密级别由procedure 元素或其祖先的security 属性决定,如果多处指定了security ,则选择据其最近的一个security 属性值。

<xsl:template match="procedure">

  <fo:block>

    <xsl:value-of select="ancestor-or-self::*[@security][1]/@security"/>

  </fo:block>

  <xsl:apply-templates/>

</xsl:template>

 

7.6.2 属性值模板

属性值模板使用{} 包含表达式,实例化的时候,表达式求值结果转化成字符串替代表达式和花括号。并非所有的属性都能解释为属性值模板,值为表达式或模式的属性、顶层元素的属性、引用命名XSLT 对象的属性不能被解释称属性值模板。

下例将源树中的photograph 元素转化成img 元素,src 属性值通过计算变量image-dir 和源节点的href 孩子值得到,width 从源节点的size 孩子元素的width 属性取得:

<xsl:variable name="image-dir">/images</xsl:variable>

 

<xsl:template match="photograph">

<img src="{$image-dir}/{href}" width="{size/@width}"/>

</xsl:template>

结果为:

<img src="/images/headquarters.jpg" width="300"/>

表达式中不能递归使用花括号,比如<a href="#{id({@ref})/title}"> 应改为<a href="#{id(@ref)/title}">

 

7.7 编号

<!-- Category: instruction -->
<xsl:number
  level = "single" | "multiple" | "any"
  count = pattern
  from = pattern
  value = number-expression
  format = { string }
  lang = { nmtoken }
  letter-value = { "alphabetic" | "traditional" }
  grouping-separator = { char }
  grouping-size = { number } />

xsl:number 元素用于向结果树中插入格式化的数字。要插入的数字可通过value 属性中的表达式指定,表达式的结果首先转化成数值,圆整为整数后按照formatlang letter-value 等属性指定的格式转化为字符串插入结果树。比如:

<xsl:template match="items">

  <xsl:for-each select="item">

    <xsl:sort select="."/>

    <p>

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

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

    </p>

  </xsl:for-each>

</xsl:template>

没有指定value 的话,则插入当前节点在源树中的位置。下列属性控制当前节点如何编号:1level 说明把源树看成多少层次,默认为single ,还可以是multipleany2count 是一个模式,说明各层上有哪些节点,默认为与当前节点类型相同的所有节点。3from 说明从几开始数。

xsl:number 元素首先使用levelcountfrom 属性构造一个正整数列表:

如果level="single" ,首先在ancestor-or-self 轴搜索和count 模式匹配的第一个节点,构造长度为1 的列表,其中包含这个祖先的前兄弟(按文档序)个数加1 。如果没有找到这样的节点,则列表为空。如果指定了from 属性,则搜索的范围仅限于from 模式匹配的最近祖先的后代。

如果level="multiple" ,则列表中按照文档顺序包括当前节点的所有祖先和当前节点,从中选择和count 模式匹配的节点,将每个节点映射为和count 模式匹配的前兄弟个数加1From 的语义同上。

如果level="any" ,首先构造一个集合,其中包括当前节点和按照文档顺序出现在当前节点之前的所有节点(不包括名称空间和属性),然后从中选择和count 匹配的节点,构造一个列表,其中包含筛选出的节点的个数。如果指定了from 属性,则集合中仅包括当前节点之前与from 模式匹配的第一个节点之后的节点。

下面对有序列表中的项进行编号:

<xsl:template match="ol/item">

  <fo:block>

    <xsl:number/><xsl:text>. </xsl:text><xsl:apply-templates/>

  </fo:block>

<xsl:template>

下面的规则对title 元素进行编号。假设文档中包含chapter (编号为123 )和appendixABC ),章(附录)中又包括section1.1 或者A.1 ),节下包括subsection

<xsl:template match="title">

  <fo:block>

     <xsl:number level="multiple"

                 count="chapter|section|subsection"

                 format="1.1 "/>

     <xsl:apply-templates/>

  </fo:block>

</xsl:template>

 

<xsl:template match="appendix//title" priority="1">

  <fo:block>

     <xsl:number level="multiple"

                 count="appendix|section|subsection"

                 format="A.1 "/>

     <xsl:apply-templates/>

  </fo:block>

</xsl:template>

下面对chapter 中的note 编号:

<xsl:template match="note">

  <fo:block>

     <xsl:number level="any" from="chapter" format="(1) "/>

     <xsl:apply-templates/>

  </fo:block>

</xsl:template>

下例对HTMLH4 元素编号:

<xsl:template match="H4">

  <fo:block>

   <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:number level="any" from="H3" count="H4"/>

   <xsl:text> </xsl:text>

   <xsl:apply-templates/>

  </fo:block>

</xsl:template>

 

7.7.1 字符串转化属性

下列属性控制数字到字符串的转换,所有属性都是可选的,数字是大于0 的整数。

Format :默认值为1 。该属性按照最大匹配原则,根据字母数字字符和非字母数字字符分解成一系列的记号。字母数字记号用于指定数字格式化,非字母数字记号用作前缀、后缀和分隔符。第n 个格式化记号用于列表中格式化第n 个数字,如果数字个数多于格式化记号,则多出的数字使用最后一个格式化记号;如果没有格式化记号,则所有数字都使用1 作为格式化记号。格式化记号用于指定表示1 的字符串。多级编码如果没有指定非字母数字字符分隔符,则默认使用句点。

可以指定格式化串的最小宽度,如01 可生成序列0109 10 1199 100 101 。格式化记号A 生成A B CZ AA AB AC …;a 生成a b cz aa ab ac;i 生成i ii iii iv v vi vii viii ix x, 类似的还有I

其他格式化记号表示编号从它而不是1 开始计数。

采用字母编号的时候, lang 属性指定用什么语言的字母表。

letter-value 用于区分编码用的字。比如汉字中可用一二三或者壹贰叁 。

grouping-separator 用于指定数字分位符(如千分位,一般为“, ”),grouping-size 指定分位长度(通常是3 ),两者必须同时指定。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值