模块化xslt?

时间:2011-12-30 15:50:19

标签: xslt

如何在xslt变换中模块化一组重复的输出?例如,我有类似以下内容(伪代码)。

<foreach "path">
  <if "count(/subPath) = 0">
    <a><value-of "x"/></a>
    <b><value-of "y"/></b>
    <c></c>
  </fi>
  <else>
    <foreach "subPath">
      <a><value-of "../x"/></a>
      <b><value-of "../y"/></b>
      <c><value-of "z"/></c>
    </foreach>
  </else>
</foreach>

并想要以下内容

<foreach "path">
  <if "count(/subPath) = 0">
     <?/>
  </fi>
  <else>
    <foreach "subPath">
       <?/>
    </foreach>
  </else>
</foreach> 
<?>
   <a><value-of "../x"/></a>
   <b><value-of "../y"/></b>
   <c><value-of "z"/></c>
</?>

我在寻找什么构造?

3 个答案:

答案 0 :(得分:2)

<强>予。伪代码翻译

您的伪代码将1:1转换为此XSLT转换

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
     <xsl:for-each select="/t/m/n/p">
       <xsl:choose>
        <xsl:when test="not(subPath)">
        <a><xsl:value-of select="x"/></a>
        <b><xsl:value-of select="y"/></b>   
      </xsl:when>
      <xsl:otherwise>
       <xsl:for-each select="subPath">
        <a><xsl:value-of select="../x"/></a>
        <b><xsl:value-of select="../y"/></b>
        <c><xsl:value-of select="z"/></c>   
       </xsl:for-each>
      </xsl:otherwise>
       </xsl:choose>
     </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

应用于此XML文档(问题中未提供此类文档!!!):

<t>
 <m>
  <n>
   <p>
     <x>1</x>
     <y>2</y>
     <subPath>
       <z>3</z>
     </subPath>
     <subPath>
       <z>4</z>
     </subPath>
   </p>
  </n>
 </m>
</t>

产生了想要的正确结果

<a>1</a>
<b>2</b>
<c>3</c>
<a>1</a>
<b>2</b>
<c>4</c>

<强> II。重构

这是一个重构的等效转换,不使用任何xsl:for-each或任何明确的条件指令

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

 <xsl:template match="p[not(subPath)]" name="processP">
   <xsl:param name="pNode" select="."/>
   <a><xsl:value-of select="$pNode/x"/></a>
   <b><xsl:value-of select="$pNode/y"/></b>
 </xsl:template>

 <xsl:template match="p/subPath">
   <xsl:call-template name="processP">
    <xsl:with-param name="pNode" select=".."/>
   </xsl:call-template>
   <c><xsl:value-of select="z"/></c>    
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

应用于同一XML文档(上图)时,再次生成相同的正确结果

<a>1</a>
<b>2</b>
<c>3</c>
<a>1</a>
<b>2</b>
<c>4</c>

请注意

  1. 模板/模式匹配,以避免使用显式条件指令。这是最强大的XSLT特定设计模式。

  2. 没有重复的代码。

  3. 在确切的要求条件下,每个模板都与其必须处理的节点完全匹配。

  4. 第一个模板的代码通过给它一个名称重新使用,以便可以显式调用它。这样就避免了代码重复。

答案 1 :(得分:0)

您可能正在寻找named templates

答案 2 :(得分:0)

您正在寻找模板(<template>),您可以使用<call-template>来调用这些模板。有关http://www.w3.org/TR/xslt#named-templates的其他详细信息。