雏菊链接xslt是一种公认​​的做法吗?

时间:2010-12-31 19:32:39

标签: xslt

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

我的问题是'这是标准做法还是我错过了什么?'

提前致谢。

斯蒂芬

3 个答案:

答案 0 :(得分:10)

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

以下是一个示例(过于简单而无意义,但完全说明了如何完成此操作):

<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元素。

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

  3. 我们现在在我们的转换链中执行第二次转换 - 在第一次转换的结果上,保持为变量$vPass1的值。不要混淆第一遍模板,我们指定新处理应该处于命名模式,称为“pass2”。在此模式下,任何num元素的值乘以2。

  4. 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>
    

答案 1 :(得分:1)

如果这是你的情况(或可能成为你的情况):

  1. 将初始xml转换为mediary xml。
  2. 也许将mediary xml转换为final1_html。
  3. 也许将mediary xml转换为final2_html(完全不像final1_html)。
    1. 将初始xml转换为mediary xml。这很可能随着时间的推移而发生变化。
    2. 将mediary xml转换为final_html。这不太可能随着时间而改变。
    3. 然后使用两步转换是有意义的。

      如果这是你的情况:

      1. 将初始xml转换为mediary xml。
      2. 将mediary xml转换为final_html。
      3. 然后考虑不是两个踩踏。而只是执行一次转换。

答案 2 :(得分:0)

我不认为这是标准练习,特别是因为您可以将一种XML方言直接转换为另一种。

但是,如果处理很复杂,将其拆分为多个步骤(在每个步骤中应用不同的转换)确实可以简化每个步骤并使其有意义。

这实际上取决于具体情况。