菊花链 xslt 是一种公认​​的做法吗? [英] Is daisy chaining xslt an accepted practice?

查看:27
本文介绍了菊花链 xslt 是一种公认​​的做法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一种情况,我认为我需要菊花链我的 xslt 转换(即一个 xslt 转换的输出被输入到另一个).第一个转换相当复杂,有很多 xsl:choice 和祖先 xpath.我的想法是将xml转换成xml,然后可以很容易地转换成html.

I have a situation where I think I need to daisy chain my xslt transformation (i.e. that output of one xslt transform being input into another). The first transform is rather complex with lots of xsl:choice and ancestor xpaths. My thought is to transform the xml into xml that can then be easily transformed to html.

我的问题是这是标准做法还是我遗漏了什么?"

My question is 'Is this standard practice or am I missing something?'

提前致谢.

斯蒂芬

推荐答案

在 XSLT 应用程序中经常使用执行一系列转换,尽管在​​ XSLT 1.0 中完全执行此操作需要使用供应商-特定的 xxx:node-set() 函数.在 XSLT 2.0 中不需要这样的扩展,因为那里消除了臭名昭著的 RTF 数据类型.

Performing a chain of transformations is used quite often in XSLT applications, though doing this entirely in XSLT 1.0 requires the use of the vendor-specific xxx:node-set() function. In XSLT 2.0 no such extension is needed as the infamous RTF datatype is eliminated there.

这是一个例子(太简单了没有意义,但完整地说明了这是如何完成的):

Here is an example (too-simple to be meaningful, but illustrating completely how this is done):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
   <xsl:variable name="vrtfPass1">
    <xsl:apply-templates select="/*/*"/>
   </xsl:variable>

   <xsl:variable name="vPass1"
        select="ext:node-set($vrtfPass1)"/>

   <xsl:apply-templates mode="pass2"
        select="$vPass1/*"/>
 </xsl:template>

 <xsl:template match="num[. mod 2 = 1]">
  <xsl:copy-of select="."/>
 </xsl:template>

 <xsl:template match="num" mode="pass2">
  <xsl:copy>
    <xsl:value-of select=". *2"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于以下 XML 文档时:

<nums>
  <num>01</num>
  <num>02</num>
  <num>03</num>
  <num>04</num>
  <num>05</num>
  <num>06</num>
  <num>07</num>
  <num>08</num>
  <num>09</num>
  <num>10</num>
</nums>

产生想要的、正确的结果:

<num>2</num>
<num>6</num>
<num>10</num>
<num>14</num>
<num>18</num>

说明:

  1. 在第一步中,XML 文档被转换,结果被定义为变量 $vrtfPass1 的值.这仅复制具有奇数(不是偶数)的 num 元素.

  1. In the first step the XML document is transformed and the result is defined as the value of the variable $vrtfPass1. This copies only the num elements that have odd value (not even).

$vrtfPass1 变量属于 RTF 类型,不能直接用于 XPath 表达式,因此我们使用 EXSLT (由大多数 XSLT 1.0 处理器实现)函数 ext:node-set 并定义另一个变量——$vPass1,其值为这棵树.

The $vrtfPass1 variable, being of type RTF, is not directly usable for XPath expressions so we convert it to a normal tree, using the EXSLT (implemented by most XSLT 1.0 processors) function ext:node-set and defining another variable -- $vPass1 whose value is this tree.

我们现在执行转换链中的第二个转换 -- 在第一个转换的结果上,保留为变量 $vPass1.为了不弄乱第一遍模板,我们指定新处理应处于命名模式,称为pass2".在这种模式下,任何 num 元素的值都乘以 2.

We now perform the second transformation in our chain of transformations -- on the result of the first transformation, that is kept as the value of the variable $vPass1. Not to mess with the first-pass template, we specify that the new processing should be in a named mode, called "pass2". In this mode the value of any num element is multiplied by two.

XSLT 2.0 解决方案(无 RTF):

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:variable name="vPass1" >
   <xsl:apply-templates select="/*/*"/>
  </xsl:variable>
   <xsl:apply-templates mode="pass2"
        select="$vPass1/*"/>
 </xsl:template>

 <xsl:template match="num[. mod 2 = 1]">
  <xsl:copy-of select="."/>
 </xsl:template>

 <xsl:template match="num" mode="pass2">
  <xsl:copy>
    <xsl:value-of select=". *2"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

这篇关于菊花链 xslt 是一种公认​​的做法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆