有趣的XSL困境

时间:2010-12-31 22:51:41

标签: xml xslt

我遇到了这个问题。

一个名为“checkbox”的模板,它在表HTML元素内部以及在其外部调用。

要解决问题,我已将<td>标记添加到“复选框”输入控件。

这是我想要做的,但我不确定它是否可能。

当我点击我的“行”(自定义表标记的一部分)模板时,我会设置一些变量或传递一些参数,对于之后应用的每个模板,它会知道它在“行”中并执行一些特殊操作根据这些信息。我知道我无法为apply-templates添加参数。我可以添加一行“模式”,但我不能对每个模板进行更改,并且只有一个带有mod参数的副本和一个没有的副本。

感谢您的任何建议。我知道理想的解决方案是对XML进行更改,但我不确定我是否可以这样做。这是一个“内容”问题。 :P

谢谢!

附录:

我将尝试更好地解释我的问题。

我有一个名为“复选框”的模板。有时我需要一个围绕调用的标签来呈现复选框,有时我不需要。我执行“复选框”模板的时间是“父”通过“行”模板调用apply-templates调用(这转换为a,因此需要复选框论坛控件)。

问题是我需要能够在两种情况下重复使用复选框模板:1)当它没有被行模板调用时以及它被行模板调用时。

我希望这更清楚。

3 个答案:

答案 0 :(得分:2)

您可以使用特定的“模式”调用模板:

<xsl:apply-templates select="*" mode="row"/>

但也可以应用带参数的模板:

<xsl:apply-templates select="*">
  <xsl:with-param name="mode" select="'row'"/>
</xsl:apply-templates>

后一种方法至少在所有可能与它们应用的元素匹配的模板(在这种情况下为'*')中声明一个名为'mode'的参数时起作用。

答案 1 :(得分:1)

  

当我点击我的“行”时(部分内容)   自定义表格标记)模板,我愿意   设置一些变量或传递一些   参数,每个模板的参数   事后申请,会知道的   在“行”中做一些特别的事情   根据这些信息。我知道我   无法添加参数   应用模板。我也许能够补充一下   一行“模式”,但我无法进行更改   到每个模板并有一个副本   使用mod参数和一个   不

首先,参数可以传递给模板,这些模板被<xsl:apply-templates>指令选中进行处理。请阅读<xsl:with-param>

但是,通常不需要传递这样的参数。这是一个例子:

如果模板与特定(当前)节点匹配,并且它必须以特殊方式操作,具体取决于此节点是否在表行中,那么这只是一个简单的检查:

parent::tr

仅在父节点为tr

时选择

ancestor::tr

选择所有祖先tr个节点

如果上面的第一个或第二个XPath表达式选择非空节点集,则(分别),当前节点的父节点 a tr,或者当前节点在某个tr内。

因此,您可以使用<xsl:when>来测试

以下是完整解决方案的外观

<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="checkbox">
  <xsl:choose>
   <xsl:when test="ancestor::tr">
     <myTag><xsl:copy-of select="."/></myTag>
   </xsl:when>
   <xsl:otherwise>
    <xsl:copy-of select="."/>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于以下XML文档

<t>
  <checkbox>1</checkbox>
  <table>
    <tr>
      <td><checkbox>1</checkbox></td>
    </tr>
  </table>
</t>

产生了想要的正确结果

<checkbox>1</checkbox>
<myTag>
   <checkbox>1</checkbox>
</myTag>

通常可以通过在匹配模式中指定具有谓词的特定模板来完全消除条件指令。如果您提供必要的相关信息,人们可能会发布一个优雅的解决方案。

答案 2 :(得分:0)

  

当我点击我的“行”时(部分内容)   自定义表格标记)模板,我愿意   设置一些变量或传递一些   参数,每个模板的参数   事后申请,会知道的   在“行”中做一些特别的事情   根据这些信息。我知道我   无法添加参数   应用模板。我也许能够补充一下   一行“模式”,但我无法进行更改   到每个模板并有一个副本   使用mod参数和一个   不

这些是XSLT 1.0的限制,通过新的mode处理和隧道参数在XSLT 2.0中解决。

在XSLT 1.0中,你可以让“穷人的隧道”覆盖“任何元素”内置规则,如:

<xsl:template match="*">
   <xsl:param name="mode"/>
   <xsl:apply-templates>
      <xsl:with-param name="mode" select="$mode"/>
   </xsl:apply-templates>
</xsl:template>

请记住将此模式转换为符合更具体元素的规则。