charminglee

xsl:number的用法

内建的编号功能是XSLT保持得最好的秘密之一,很遗憾人们对这个功能知之甚少,这个功能可以简化许多转换使用的复杂的编号任务。XSLT提供一个名为xsl:number的元素:它使 我们将格式化好的编号插入到结果文档成为可能。 你可以使用该元素的下列各种属性去影响编号在结果文档中产生的方式以及格式化处理的方式。
<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元素首先求得在值属性中提供的表达式的值,接着结果对象被转换为某个编号,就像调用XPath 的 number 函数一样。 编号然后被四舍五入到 为一整数,并依照最后五个属性值(format, lang, letter-value, grouping-separator, and grouping-size)被格式化。xsl:number 的所有属性描述 参见 Figure 4
下面是一个XSLT语句例子:
<xsl:number value="5000000 div 3"
grouping-separator="," grouping-size="3" />
这个表达式在结果树中显示如下:
      1,666,667       
  但是通常情况下都省略值属性,由xsl:number自动计算。当你不指定值属性时,xsl:number计算并以当前节点位置为值。level, count, 和 from 属性 影响当前节点位置的计算方式。from属性的计算模式确定了从树的何处开始计算,而count属性的计算模式确切给出应该计算哪个节点,level 属性指定 了在计算过程中应该考虑源树的哪些层次。
  level可能的值有三种:“single”、“any”和“multiple”。single值计算目标节点之前的兄弟节点(即 XPath 的前兄弟轴。译者注:preceding-sibling表示当前节点的所有在它之前的兄弟节点),如果当前节点 与计算模式匹配,或者没有指定计算,那么当前节点即为目标节点。否则,目标节点就是与该计算模式匹配的第一个祖先节点。与from模式匹配的第一个祖先 节点(当前节点的)确定了计数开始节点始于何处。只有那些从开始节点到当前节点之间的节点被计算。
  文档次序中当前节点之前节点的“any”节点计数值由计算模式确定,(即 XPath 的preceding 轴和 ancestor-or-self 轴的合并)。 与from模式匹配的(当前节点之前的)第一个节点指定计算从哪个节点处开始。只有那些从开始节点到当前节点之间的节点被计算。
  “multiple”计算产生一个序列编号,每个编号的产生方式与产生单一层次的计数值相同(例如 1.1.1 , 1.1.2, 1.2.1等等)。与 count 模式匹配的最外 层的祖先的计数值为序列的第一个编号。接下来次外层祖先的计数值为序列的第二个编号,如此类推。与 count 模式匹配的最里层祖先计数值为序列的最后一个编号。每一个祖先 的计数值的确定与单层计数一样。
  下面让我们看看几个例子。下面是一个包含了sample book 结构的XML文档。
<books>
<book title="Sample Book">
<chapter title="Sample Chapter">
<section title="Sample Section">
<p>This is some sample text.</p>
...
  在这个特定的 schema 中,books元素可能包含几个book元素,每个book元素可能包含多重chapter元素,每个chapter元素有可能包含多重section元素。下面的转换使用默认的xsl:number功能(level=”single”)来计算 books、chapters 和 sections 的 编号。
<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="book">
<xsl:number/>.<xsl:value-of select="@title"/>
<xsl:apply-templates/>
</xsl:template>
...
</xsl:transform>
  这个转换产生的文本见 Figure 5(添加空白字符为提高可读性)。注意book、chapter和section计数是被独立的保持下来。现在参看一下Figure 6中的使用level=“any”的转换。
  在“any”方式下,chapter编号不再在book的包含范围之内,section编号也不再在chapter的包含范围之内。现在的chapter和sectoin在整个文档中从开始到结束以连续的方式被编号,见Figure 7。如果你想让每个编号项包含祖先级别编号(例如 1.2.1 ),那么你使用level的“multiple”值。
  在“multiple”方式下,你具体指定出一个模式,显示的在诸多祖先中你想计数哪些节点,如下所示:
<xsl:template match="book">
<xsl:number level="multiple"/>. <xsl:value-of select="@title"/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="chapter">
<xsl:number level="multiple" count="chapter|book"/>.
<xsl:value-of select="@title"/>
<xsl:apply-templates/>
</xsl:template>
  注意到你不必为book元素作任何专门的处理,因为它是最外面直到计数结束的元素。然而,对chapter元素,你必须具体指定出你想计数book和chapter的元素;对section元素你也必须具体指出你想计数section、chapter和book的元素。这个例子产生的编号列表见Figure 8
  当使用这些技术的时候,你也可以使用 format 属性去控制怎样格式化编号。在前面的例子中,硬编码句号使之跟随在产生的编号数字之后, 我可能已经通过使用下面的format属性完成了这些:
<xsl:template match="book">
<xsl:number level="multiple" format="1. "/>
<xsl:value-of select="title"/>
<xsl:apply-templates/>
</xsl:template>
  你可能也想在你的编号schema中使用罗马数字(例如:I、II、III、IV等等)或者按字母顺序的字符(例如:A、B、C、D等等),这是可行的,要通过详细指定一个专门的format属性值。Figure 9提供了一些格式表示的例子以及对每种格式编号序列的实例值。例如Figure 10里的转换,使用罗马数字为book编号,用按字母顺序的字符为chapter编号,用阿拉伯数字为section编号。
  这种转换产生了象前面同样的编号列表,但格式化的层次不同。
I. Sample Book
I.A. Sample Chapter
I.A.1.Sample Section
I.A.2.Sample Section
I.A.3.Sample Section
I.B. Sample Chapter
I.B.1.Sample Section
...
II. Sample Book
II.A. Sample Chapter
II.A.1.Sample Section
II.A.2.Sample Section
...
  正如你看到的,只要你理解了XSLT提供的编号功能是怎样运作的,它对你的转换是一个强大而又灵活的补充。

Figure 4  xsl:number属性

名  称 默认值 描  述
level "Single" 指定在计数过程中应该考虑源树的哪些级别
count 匹配当前节点类型和名称的样式 指定的level(见level属性)的样式,样式详细指定哪些节点应该被计数的
from / 指定计数从哪里开始的样式
value 当前节点的位置 (基于其他属性)

一个XPath表达式,其结果被强制为一个数字值。 如果没有被指定,则为当前节点的位置,和level, count和 from 属性有关

format 1 指定编号格式
lang 决定于系统环境 指定在按字母顺序编号时使用哪一种语言的字母表
letter-value (无)

消除不同的已给定语言的编号方案之间的歧义,英文中,“a”格式符识别一个字母序列(例如:a,b,c,...,aa,ab,ac,...),而“i”格式符识别一个数字字母序列(例如:i,ii,iii,iv,...)。在一些语言里,存在两种编号方案编号开始于同样的字母。这种情况下,"alphabetic"值的letter-value 识别字母序列而"traditional" 值的letter-value识别其他形式

grouping-separator (无)

指定分隔符,在十进制序列中作为一个分组分割使用(例如1,000,000)

grouping-size (无) 指定分组的大小(例如:在grouping-separator的例子里大小为3)

Figure 5   独立编号方式


1. Sample Book 1. Sample Chapter 1. Sample Section 2. Sample Section 3. Sample Section 2. Sample Chapter 1. Sample Section ••• 2. Sample Book 1. Sample Chapter 1. Sample Section 2. Sample Section 3. Sample Section 2. Sample Chapter 1. Sample Section •••

Figure 6    使用any 转换


<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="book"> <xsl:number level="any"/>. <xsl:value-of select="@title"/> <xsl:apply-templates/> </xsl:template> <xsl:template match="chapter"> <xsl:number level="any"/>. <xsl:value-of select="@title"/> <xsl:apply-templates/> •••

Figure 7   连续编号方式


1. Sample Book 1. Sample Chapter 1. Sample Section 2. Sample Section 3. Sample Section 2. Sample Chapter 4. Sample Section 5. Sample Section 6. Sample Section 3. Sample Chapter 7. Sample Section 8. Sample Section 9. Sample Section 2. Sample Book 4. Sample Chapter 10. Sample Section 11. Sample Section 12. Sample Section 5. Sample Chapter 13. Sample Section •••

Figure 8   多级编号


1. Sample Book 1.1. Sample Chapter 1.1.1. Sample Section 1.1.2. Sample Section 1.1.3. Sample Section 1.2. Sample Chapter 1.2.1. Sample Section 1.2.2. Sample Section 1.2.3. Sample Section 1.3. Sample Chapter 1.3.1. Sample Section 1.3.2. Sample Section 1.3.3. Sample Section 2. Sample Book 2.1. Sample Chapter 2.1.1. Sample Section 2.1.2. Sample Section 2.1.3. Sample Section 2.2. Sample Chapter 2.2.1. Sample Section •••

Figure 9   xsl:number标记格式示例

符号 序  列
1 1, 2, 3, 4, ..., 10, 11, 12, ..., 20, 21, ...
01 01, 02, 03, 04, ..., 10, 11, 12, ..., 100, 101, ...
A A, B, C, D, ..., Z, AA, AB, AC, ...
a a, b, c, d, ..., z, aa, ab, ac, ...
I I, II, III, IV, V, VI, ..., X, XI, ...
i i, ii, iii, iv, v, vi, ..., x, xi, ...

Figure 10   含有多种编号方式的Scheme


<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:template match="book"> <xsl:number level="multiple" format="I. "/> <xsl:value-of select="@title"/> <xsl:apply-templates/> </xsl:template>
<xsl:template match="chapter"> <xsl:number level="multiple" count="chapter|book" format="I.A. "/> <xsl:value-of select="@title"/> <xsl:apply-templates/> </xsl:template>
<xsl:template match="section"> <xsl:number level="multiple" count="section|chapter|book" format="I.A.1. "/> <xsl:value-of select="@title"/> </xsl:template> ••• </xsl:transform>

posted on 2006-10-27 15:15  charming  阅读(634)  评论(0)    收藏  举报

导航