`
persistC
  • 浏览: 73078 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

XSLT 2.0 的新特性

    博客分类:
  • XSLT
阅读更多

XSLT 2.0 的新特性

关键字: XSLT, XML
原作:Evan Lenz 2002.4.10, onestab 译自 www.xml.com

本文将看看最新的工作草案中所列出的XSLT2.0的一些新特性,当然,假定你已经熟悉XSLT/XPath1.0的基本知识。

XSLT 2.0 和 XPath 2.0

XSLT 2.0 与 XPath 2.0 携手并肩。之所以将它们分开描述,是因为 XPath 2.0 也可用于XSLT之外的环境,比如XQuery 1.0。但是对于XSLT用户来说,它们是互相关联的。你不能在XSLT 1.0 中使用 XPath 2.0,或者在 XSLT 2.0 中使用 XPath 1.0。(至少到目前为止,W3C还没有这种组合的提议。)

你也许会问:XSLT 1.1 发生了什么?XSLT 1.1 已经取消了。官方的说法是在2001年8月,实际上在几个月前,XSLT工作组中止了XSLT 1.1,集中力量开发XSLT和XPath 2.0,将XSLT 1.1 的前期要求转到XSLT 2.0。

欢迎到来

许多的XSLT用户在很大程度上参与了新版XSLT的制订过程。就像许多语言的第一版一样,不经过实践的检验,这个语言的哪些扩展被证明是最重要的往往不很清楚。自从1999年11月16日XSLT 1.0 成了推荐标准以后,显然在某些方面缺少的功能应当在下一个版本中包括进来,本文我们将从下面四个方面看看XSLT 2.0:

  • 从结果树片断(result tree fragments)到节点集(node-sets)的转化
  • 有多个输出的文档
  • 对分组的内在支持
  • 用户定义函数(以XSLT实现)

RTF的末日

在XSLT 1.0 中结果树片断(Result Tree Fragment,RTF)类型很像节点集,实际上却是个二等公民。当你使用xsl:variable构建一个临时树的时候,得到的就是RTF。问题是你不能使用XPath表达式访问这个树的内容,除非你使用一个供应商提供的扩展函数,通常是node-set()之类,来把这个RTF转化成一类节点集(含有一个根节点)。这种RTF数据类型的存在本来是为了减少实现时的限制,但由于几乎所有的XSLT处理器都提供诸如node-set()之类的扩展函数,这种考虑显得有些不切实际。不管怎样,突破这种限制的呼声总会越来越明显,因为把复杂的变换分解成一系列简单的变换非常重要。

不知道你有没有猜出来,XSLT 2.0 为RTF打开了这个门。现在当你使用xsl:variable创建一个临时树,这个变量的值就是个真正的节点集。事实上,用XPath 2.0 的术语来讲,它是个真正的节点序列(true node sequence),包含一个 document node (这是一个XPath 2.0 的名称,也就是XPath 1.0 的"root node")。在这个序列上你可以使用XPath表达式深入到这棵树,对它应用模板(template)等等,就像使用其它源文件一样。有了XLST 2.0 就不再需要node-set()之类的扩展函数。

允许多个输出文档

许多XSLT 1.0 处理器所提供的另一个扩展就是多个输出文档,这种扩展被证明非常有用,对具有多个页面的网站的静态生成尤其如此。问题在于这个扩展功能不是标准的。每个处理器完成这种扩展的元素都不一样,例如 saxon:output, xt:document等等。

XSLT 2.0 使用 xsl:result-document元素提供了多个输出文档的一个标准方法。下面的样式表例子构建了多个输出文档,一个“主要结果文件”和几个“次级结果文件”。主要结果文件以XHTML存储,次级结果文件以纯文本方式存储。

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://www.w3.org/1999/xhtml">
  <xsl:output method="xhtml"/>
  <xsl:output method="text" name="textFormat"/>
  <xsl:template match="/">
    <html>
      <head>
        <title>Links to text documents</title>
      </head>
      <body>
        <p>Here is a list of links to text files:</p>
        <ul>
          <xsl:apply-templates select="//textBlob"/>
        </ul>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="textBlob">
    <xsl:variable name="uri" select="concat('text', position(), '.txt')"/>
    <li>
      <a href="{$uri}">
        <xsl:value-of select="$uri"/>
      </a>
    </li>
    <xsl:result-document href="{$uri}" format="textFormat">
      <xsl:value-of select="."/>
    </xsl:result-document>
  </xsl:template>
</xsl:stylesheet>

xsl:document href 属性用来为相应的输出文件指定一个URI。对于许多处理器来说,这意味着以该文件名存储文件。而format属性用来引用一个已命名的指定输出。在这里,它指向以textFormat命名的xsl:output元素。

上例中的XHTML输出方式也是在XSLT 2.0中新引入的,这里勿须赘言。

简化的分组

XSLT 1.0 没有对分组的内在支持。特定的分组问题无疑可使用各种技巧解决,例如Muenchian方法,但是这种解决方法相当复杂难懂。对XSLT 2.0 的要求之一就是必须要简化分组,就像我们在下例中所看到的,这种方法能满足要求。

出现在 Requirements document 和XSLT 2.0 工作草案的这个例子是关于把下面简单XML文档中的城市列表,

<cities>
  <city name="milan"  country="italy"   pop="5"/>
  <city name="paris"  country="france"  pop="7"/>
  <city name="munich" country="germany" pop="4"/>
  <city name="lyon"   country="france"  pop="2"/>
  <city name="venice" country="italy"   pop="1"/>
</cities>

转换为如下所示的以国家进行分组的HTML表格:

<table>
   <tr>
      <th>Country</th>
      <th>City List</th>
      <th>Population</th>
   </tr>
   <tr>
      <td>italy</td>
      <td>milan, venice</td>
      <td>6</td>
   </tr>
   <tr>
      <td>france</td>
      <td>paris, lyon</td>
      <td>9</td>
   </tr>
   <tr>
      <td>germany</td>
      <td>munich</td>
      <td>4</td>
   </tr>
</table>

这种转换的难点在于生成最后三行(如粗体所示)。下面是XSLT1.0的一种解决方案:

  <xsl:for-each select="cities/city[not(@country =
                           preceding::*/@country)]">
    <tr>
      <td><xsl:value-of select="@country"/></td>
      <td>
        <xsl:for-each select="../city[@country = current()/@country]">
          <xsl:value-of select="@name"/>
          <xsl:if test="position() != last()">, </xsl:if>
        </xsl:for-each>
      </td>
      <td><xsl:value-of select="sum(../city[@country =
                 current()/@country]/@pop)"/></td>
    </tr>
  </xsl:for-each>

在上例中,对每个特定的国家,我们首先要用下面的XPath表达式找出它的第一个城市:

cities/city[not(@country = preceding::*/@country)]

然后,对每个分组,为了获得每个国家的城市名字列表以及该国的总人口,我们需要再回头引用该组的所有其他成员,这两种情况我们不得不作一些额外的工作,因为只能用下面的表达式才能引用到当前的分组:

../city[@country = current()/@country]

显然这不是个理想的局面,因为这种额外的代码往往是错误之源。 使用 xsl:for-each-group, XSLT 2.0 为你的大多数分组问题提供了答案。下面就是XSLT2.0对这个问题的解决办法(粗体表示新特性):

  <xsl:for-each-group select="cities/city" group-by="@country">
    <tr>
      <td><xsl:value-of select="@country"/></td>
      <td>
        <xsl:value-of select="current-group()/@name" separator=", "/>
      </td>
      <td><xsl:value-of select="sum(current-group()/@pop)"/></td>
    </tr>
  </xsl:for-each-group>

在上例中,xsl:for-each-group 作为XPath的取值上下文的一部分,对"current group"进行初始化,当前的分组是一个简单序列。一旦我们使用group-by属性设置好分组,以后就可以使用current-group()函数引用当前的分组。这就完全消除了XSLT1.0方案中的额外开销。

注意xsl:value-of中的separator属性。这个属性的存在是为了告诉处理器不只是要输出这个序列中的第一个元素的string值(XSLT1.0是如此作的),而是要按顺序输出该序列中所有元素的值。separator属性的取值为一个可选的字符串,用作输出中每个字符串的分隔符。为了与XSLT1.0兼容,如果没有指定separator属性,只输出该序列中的一个成员的值。

 

最后,根据xsl:for-each-group的三个属性的取值,可以解决不同的分组问题:group-by(如上面所示),goup-adjacent(用于根据文当中的节点顺序的相邻关系进行分组,例如将inline的<para>元素转化为块级(block)的<para>元素),以及group-start-with(根据序列中元素的模式(patterns)分组)。这些方法的例子可以在最新的XSLT2.0工作草案的"13.3 Examples of Grouping"中找到。

用户定义函数

XSLT2.0引入了一个新特性,就是允许定义他们自己的函数,并可以在Xpath表达式中使用。这是个非常强大的功能,无疑是非常有用的。样式函数(Stylesheet functions)是用xsl:function元素定义的。这个元素必须指定一个name属性。它包含0个或多个xsl:param元素,然后是0个或多个xsl:variable元素,后面是唯一的xsl:result元素。这种严格的内容模型看起来是个限制,但是你会发现XSLT2.0的真正强大之处就在于可定义xsl:result元素的select属性。你可能会想到,XPath2.0具备有条件表达式(if...then)和迭代(iterative)(列举?)表达式(for...return)。

就像下面例子(直接取于最新的工作草案)所示,许多工作是在xsl:resultselect属性中完成的。这个样式表调用了用户自定义的一个递归函数str:reverse()来输出字符串"MAN BITES DOG"。

<xsl:transform 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:str="http://user.com/namespace"
  version="2.0"
  exclude-result-prefixes="str">
<xsl:function name="str:reverse">
  <xsl:param name="sentence"/>
  <xsl:result 
     select="if (contains($sentence, ' '))
             then concat(str:reverse(substring-after($sentence, ' ')),
                         ' ',
                         substring-before($sentence, ' '))
             else $sentence"/>             
</xsl:function>
<xsl:template match="/">
<output>
  <xsl:value-of select="str:reverse('DOG BITES MAN')"/>
</output>
</xsl:template>
</xsl:transform>

其他有用的东西动手试试

XSLT2.0还有其他有用的新特性,我们在这里难以祥述。包括一种机制,可定义XPath表达式的缺省名称空间(namespace),可在模式匹配判定(match pattern predicates)中使用变量,为排序说明命名(named sort specifications),以非解析文本(unparsed text)的方式读入外部文件等等。

此外,XSLT2.0说明书的一大部分仍在制订中,特别是有关构建和复制W3C XML Schema类型的内容。关于这点,最新的工作草案中说,“这项工作正在进行,有关构建元素和属性的类型信息关联,将可能会出现在XSLT2草案的未来版本中。(This is work in progress. Facilities for associating type information with constructed elements and attributes are likely to appear in future drafts of XSLT 2)”。

如果你迫不及待地想试试这些新东西,Michael Key已经发布了Saxon 7.0,包含一个“实现XSLT2.0和XPath2.0的尝试”。它实现了XSLT2.0和XPath2.0的一些新特性,特别值得关注的是这些特性看起来非常稳定。我对本文中的每个例子都作了测试,正如所期待的那样,Saxon 7.0 能够全部运行这些例子。

XSLT2.0很大程度上仍然处于起草阶段,所以要预先指出,从目前阶段到成为推荐标准中间,有些东西可能会发生变化。目前,鼓励大家浏览说明文件并将他们的观点发送到 xsl-editors@w3.org。

分享到:
评论

相关推荐

    xslt2.0l资料1

    XSLT 2.0在XSLT 1.0的基础上增加了许多新特性,使得XML数据处理更为强大和灵活。 该压缩包中的“Wrox.Press.XSLT.2.0.Programmers.Reference.Third.Edition.eBook-LiB.chm”文件,是这本书的电子版,通常以CHM...

    Beginning XSLT 2.0 From Novice to Professional

    相较于早期版本,XSLT 2.0引入了许多重要的改进和新功能,这些新特性极大地增强了XSLT的能力。以下是一些关键的变化: 1. **XPath 2.0支持**:XSLT 2.0使用XPath 2.0作为其查询语言,这意味着可以使用更强大的XPath...

    XML XML Schema XSLT 2.0和XQuery开发详解源代码.rar

    XSLT 2.0是其第二个主要版本,引入了许多新特性,如支持函数库、正则表达式、格式化数字和日期等。通过XSLT,可以将XML数据转换成其他格式,如HTML、PDF或CSV,以适应不同的展示需求。 XQuery是一种查询XML数据的...

    Wrox.XSLT.2.0.and.XPath.2.0.Programmers.Reference.4th.Edition.May.2008.rar

    XSLT 2.0是XSLT的第二个主要版本,引入了许多新特性,如模式选择、函数库的扩展、支持变量和参数、流式处理,以及对XML Schema的集成。它提供了更强大的功能,使得复杂的XML数据转换变得更加容易和高效。例如,你...

    XSLT.2nd.Edition.Jul.2008.pdf

    XSLT 2.0 在功能上有了显著增强,包括对XPath 2.0的支持、更强大的数据类型支持以及改进的性能特性。 #### 核心概念与特点 1. **XPath 2.0 支持**:XSLT 2.0 引入了对XPath 2.0 的支持,这使得开发者能够更方便地...

    Gestalt XSLT 2.0 processor-开源

    XSLT 2.0是XSLT的第二个主要版本,引入了许多新功能和改进,如支持函数库、模式匹配、流控制等。 描述中提到的“基本级”可能意味着Gestalt是一个基础且核心的实现,专注于XSLT的核心转换功能,而不是一个包含大量...

    Beginning XSLT and XPath Transforming XML Documents and Data

    本书不仅覆盖了XSLT和XPath的基础知识,还深入介绍了XSLT 2.0的新特性和XPath 2.0的强大功能。通过大量的代码示例和实际应用场景,旨在帮助读者从零开始系统地掌握XSLT和XPath的核心技术,并能够将其应用于实际工作...

    Beginning.XSLT.and.XPath_Transforming.XML.Documents.and.Data源码

    在《XSLT 2.0 and XPath 2.0 Programmer's Reference (Programmer to Programmer)》这本书中,读者可以深入学习XSLT 2.0和XPath 2.0的新特性,比如支持函数库的扩展、流式处理以及更强大的类型系统。XSLT 2.0引入了...

    Beginning xml

    - **XSLT 2.0的新特性**: - **更强大的XPath支持**:XSLT 2.0引入了XPath 2.0,提供了更丰富的路径表达式语法,支持更多的数据类型和函数。 - **变量作用域**:增加了局部变量的概念,使得变量的作用范围更为明确...

    xslt手册

    6. XSLT 1.0与XSLT 2.0/3.0的区别:XSLT 2.0引入了许多新功能,如正则表达式支持、函数库扩展、更多数据类型和更强大的样式表组合能力。XSLT 3.0进一步增强了这些特性,如支持静态类型检查、流式处理API和异步处理。...

    Java SE 6 新特性

    8. **XPath和XSLT 2.0支持**:Java 6支持XPath 2.0和XSLT 2.0标准,提供了更强大的XML处理能力,可以进行更复杂的XML数据操作。 9. **改进的调试和诊断工具**:JConsole、VisualVM等Java Mission Control的组件在...

    XSLT与XPath入门转换XML文档与数据

    - 提供了XSLT 2.0的主要特性和语法概览。 - **附录E:XSLT 2.0 Schema** - 描述了XSLT 2.0的Schema定义。 - **附录F:XPath 2.0函数参考** - 列出了XPath 2.0中可用的所有函数及其用法。 - **附录G:参考资料*...

    XPath 2.0 程序员参考

    - **XSLT 转换**:XPath 2.0 作为 XSLT 2.0 的一部分,在进行复杂的 XML 转换时发挥着核心作用。 - **XML 数据验证**:利用 XPath 2.0 的丰富类型系统和内置函数,可以在文档级别进行数据验证。 - **数据库查询**:...

    xslt.rar_xslt

    此外,XSLT 2.0及更高版本引入了许多新特性,比如变量和函数的可重用性、流式处理以及支持XML Schema的数据类型,这些都可能在书中有所介绍。 附带的文本文件“www.pudn.com.txt”可能包含了获取该资源的网站信息或...

    .NET中的XSL 2.0和XQuery 1.0

    首先,XSLT 2.0是XSLT 1.0的升级版,它引入了许多新特性,如更好的类型系统、变量和函数的重用、模式选择以及更强大的文本处理功能。例如,XSLT 2.0允许开发者在模板中声明变量,这在处理复杂逻辑时非常有用。此外,...

    XSLT Quickly

    8. **XSLT 2.0及更高版本**:尽管书可能主要基于早期版本的XSLT,但可能也会提及XSLT 2.0引入的新特性,如模式分组、函数库扩展和流式处理等。 9. **实际应用**:书中可能会通过实例演示如何使用XSLT解决实际问题,...

    XSLT从入门到精通(PDG)

    另外,XSLT 2.0和XSLT 3.0版本引入了许多新特性,如XPath 2.0/3.0的增强功能、流式处理和支持函数库的导入。教程会对比不同版本间的差异,使读者能够适应不断演进的技术环境。 最后,为了帮助读者更好地实践和巩固...

    xslt 扩展PDF教程

    我们将关注于XSLT扩展元素与函数的应用,以及如何在实际场景中使用这些特性。 知识点: ### 1. XSLT与EXSLT简介 XSLT是一种用于XML文档转换的语言,它允许开发者将源XML文档转换为HTML、PDF或任何其他格式的输出...

    xslt标准

    - **XSLT 2.0**:于2007年发布,引入了许多新功能,如序列类型、正则表达式路径步骤等,显著增强了XSLT的能力。 - **XSLT 3.0**:进一步改进了处理大规模数据集的能力,支持更复杂的查询和表达式。 #### 三、XSLT的...

Global site tag (gtag.js) - Google Analytics