打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
用于数据的 XML: XPath 2.0 有哪些新特性?
userphoto

2005.11.02

关注
内容:
xf:distinct-values 函数
xf:document 函数
xf:current-dateTime 函数
更佳的 XML 模式兼容性
参考资料
关于作者
对本文的评价
相关内容:
XSLT 2.0:早期研究
在 Java 中使用 DOM 和 XPath 进行有效的 XML 处理
订阅:
developerWorks 时事通讯
对 XPath 2.0 计划采用的一些特性的前瞻

Kevin Williams
CTO, Blue Oxide Technologies,LLC
2003 年 1 月

Kevin Williams 研究了 XPath 2.0 规范的最新状态,并且提供了一些 XPath 2.0 特性的特定示例,这些特性会使 XML 开发人员的工作更加轻松。示例是用 XML 和 XPath 的形式提供的。

XSLT 1.0 和 XPath 1.0 最初是打算为 XML 文档提供简单的样式语言支持,主要是将这些文档转换成 HTML 以呈现在浏览器中。但是,自从 XSLT 和 XPath 可以使用之后,它们就被强行用于各种任务中,而这些任务 ― 从 XML 文档中复杂的数据操作(聚合、单值选择和关系旋转)到一种 XML 形式向另一种形式的 XSLT 转换 ― 并不是它们的设计初衷。在这些规范的版本 2.0 中,W3C 试图使 XSLT 和 XPath 更加灵活和健壮,以便于处理这些技术的新用法。

在上一篇专栏文章中,我研究了 XSLT 的一些新特性。在本篇专栏文章中,我只研究 XPath2.0 的几个要点 ― 由于要点太多,因而无法在一篇专栏文章中全部研究。

对于本专栏而言,特定前缀的映射含义如下:

  • xf: 前缀被认为映射到 XPath 2.0 函数名称空间(http://www.w3.org/2002/08/xquery-functions)。
  • xsl: 前缀映射到 XSLT 2.0 名称空间。
  • xs: 前缀映射到 XML 模式名称空间。

xf:distinct-values 函数
在使用 XSLT 1.0 样式表时,开发人员面临的最重大的挑战之一就是编写与 SQL 中 SELECT DISTINCT 等同功能的 XML 代码 ― 即一个获取节点集并返回那些节点唯一值列表的表达式。在 XSLT 1.0 和 XPath 1.0 中这不是不可能实现的,但都是极其困难的。基本上,您都必须写一条 xsl:for-each 语句以特殊的排序顺序对每个节点求值,然后不断回头查看节点列表,以了解是否所有匹配特定值的任何其它节点都被处理了。有了 XSLT 2.0 ,以及引入了 xf:distinct-values 函数,这个问题就迎刃而解了。下面 清单 1中是一个 XML 文档的快速示例:

清单 1. 带有作者姓名的 books
<books>  <book author="Kevin Williams" title="Professional XML 2.0" />  <book author="Lewis Carroll" title="Alice in Wonderland" />  <book author="Lewis Carroll" title="Through the Looking-Glass" /></books>

假定您想要标准化输出作者信息,并创建一个类似 清单 2的文档:

清单 2. 带有书名的 authors
<authors>  <author name="Kevin Williams">    <book title="Professional XML 2.0" />  </author>  <author name="Lewis Carroll">    <book title="Alice in Wonderland" />    <book title="Through the Looking-Glass" />  </author></authors>

要做到这一点,使用 XPath 和 XSLT 1.0 时,需要做类似于 清单 3的工作:

清单 3. XPath 1.0 中的 SELECT DISTINCT
<xsl:template match="books">  <authors>    <xsl:for-each select="book">      <xsl:sort select="@author" />      <xsl:variable name="thisAuthor">        <xsl:value-of select="@author" />      </xsl:variable>      <xsl:if test="count(preceding-sibling::book)=0">        <author name="{$thisAuthor}">          <xsl:for-each select="../book[@author=$thisAuthor]">            <book title="{@title}" />          </xsl:for-each>        </author>      </xsl:if>      <xsl:if test="preceding-sibling::book[1]/@author != $thisAuthor">        <author name="{$thisAuthor}">          <xsl:for-each select="../book[@author=$thisAuthor]">            <book title="{@title}" />          </xsl:for-each>        </author>      </xsl:if>      </xsl:for-each>    </authors></xsl:template>

记录文档的过程稍微有点凌乱和困难,但是使用 xf:distinct ,这会变的很容易,如 清单 4所示:

清单 4. XPath 2.0 中的 xf:distinct
<xsl:template match="books">  <authors>    <xsl:for-each select="xf:distinct(book/@author)">      <xsl:variable name="thisAuthor"><xsl:value-of select=".">      <author name="{$thisAuthor}">        <xsl:for-each select="book[@author=$thisAuthor]">          <book title="{@title}" />        </xsl:for-each>      </author>    </xsl:for-each>  </authors></xsl:template>

这与 xsl:for-each-group 有什么区别呢?任何实现 XPath 的地方都可以使用 xf:distinct ― 因此,它可以作为 XQuery 1.0 的一部分及专门的 XPath 处理器使用。利用 xf:distinct ,可以在值集合上执行其它操作,这与 xsl:for-each-group 相反,后者强制对不同的值单独进行操作。

这一变化解决了 XSLT 作者在试图样式化文档时遇到的许多问题。XSLT 还有许多其它变化,样式表程序员会发现它们非常有用。

xf:document 函数
在 XSLT 1.0 中使用多个文档是有问题的。XPath 2.0 的设计人员明智地选择了通过 xf:document 机制来包括额外的文档处理能力。该函数允许从 URL 装入一个或多个文档,并进行处理。例如,假定您在资源库中拥有 清单 5、6 和 7中所示的文档类型:

清单 5. 样本零件文档 1
<part name="Grommets" size="3 in." color="blue" />

清单 6. 样本零件文档 2
<part name="Grommets" size="3 in." color="blue" />

清单 7. 样本零件文档 3
<part name="Grommets" size="3 in." color="blue" />

假定您现在在一个目录中有 500 个这样的文档,您希望创建您所拥有的所有蓝色零件的列表。无需利用中间层语言(如 Java)编写代码以装入所有这些文档并查找颜色为蓝色的零件,可以编写一个列出在哪可以找到所有零件的索引(请参阅 清单 8):

清单 8. 零件索引文档
<parts>  <part file="part1.doc" />  <part file="part2.doc" />  <part file="part3.doc" /></parts>

您可以编写一个为您完成这项工作的样式表,其代码片段类似于 清单 9

清单 9. 用于跨文档的 xf:document
<xsl:template match="parts">  <blueParts>    <xsl:for-each select="xf:document(part/@file)/@color=‘blue‘">      <part name={@name} size={@size} color={@color} />    </xsl:for-each>  </blueParts></xsl:template>

这种技术特别适用于分布式网络的内容,在分布式网络中,零件信息可以放在一台服务器上,而客户信息可以放在另一台服务器上。通过利用样式表(使用 xf:document 从其它 URL“拉”信息),允许该数据可以在创建它的地方起作用。

xf:current-dateTime 函数
将样式表应用于 XML 文档时,在输出中包含已转换结果的创建日期通常都很有用。当创建 HTML 文档以驱动用户界面时,这特别重要;此类信息可以帮助高速缓存系统知道什么时候信息的副本失效了。使用 XPath 2.0 中的 xf:current-dateTime 函数可以获得当前日期和时间(请参阅 清单 10):

清单 10. xf:current-dateTime 示例
<xsl:value-of select="xf:current-dateTime()" />

这可能会返回 清单 11中所示的字符串:

清单 11. xf:current-dateTime 样本结果
2002-09-17T18:22:08z

然后,可以“按现状”使用该字符串,或者将其转换成不同的日期格式,以便于在生成的文档中使用。

更佳的 XML 模式兼容性
因为 XPath 2.0 目前在 XSLT 2.0 和 XQuery 1.0 之间共享,因此,XPath 需要更健壮的 XML 模式支持。实际上,XPath 2.0 中的整个数据模型目前都是强类型的:而不是简单的字符串、数字和布尔类型,值目前使用了作为 XML 模式规范一部分定义的原语。提供了完整的函数集,因此可以把这些值显式地从一种类型转换为另一种类型,将这种转换作为它们在 XPath 2.0 中操作的一部分。例如,通过使用类型名称可以将一个值强制转换为另一种类型,就象是一个函数一样。因此,使用 清单 12中的代码片段,可以将值强制转换为无符号整数:

清单 12. XML 模式类型强制转换示例
xs:unsignedInt(item)

XPath 2.0 中的强类型确保由 XSLT 样式表创建的文档能够依据强类型的 XML 模式进行验证。在 XSLT 2.0 之前,没有方法可以保证这一点(例如,保证数字是无符号整数)― 为了确保样式表不提供错误值,XML 模式验证步骤是必需的。

在本文中,我只是略微谈及了 XPath 2.0 必须提供的一些要点。虽然距离这项技术提升为建议书状态还有一段时日(至少 6 个月),但是,熟悉 XPath 2.0 的特性和功能将有助于您在开始实现时能够充分利用它。

参考资料

关于作者
Kevin Williams Blue Oxide Technologies,LLC 的技术主管(CTO),该公司从事 XML 和 XML Web 服务设计软件的设计业务。请访问该公司的网站 http://www.blueoxide.com。可以通过 kevin@blueoxide.com向 Kevin 提出意见。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
XSLT 介绍 - XPath介绍
XSL基本概念
xslt轻松入门(zt)
PHP5操作XML的新特性 控制 读写 dom
C#操作XML
欢迎光临 - 琳婕小筑-老猫的理想 - XSLT轻松入门 -
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服