【问题标题】:looping through parameters in xsl:template to do something whenever empty循环遍历 xsl:template 中的参数以在为空时执行某些操作
【发布时间】:2016-12-13 14:20:58
【问题描述】:

我有一个 xml 文件,其中包含一些信息,属于创建的图表。我可以用 xslt 提取我想要的所有变量。要将它们打印到另一个文件,我调用不同的模板并将变量发送给它: 例如我的主 xslt 文件中的一些代码:

<xsl:call-template name="HostDefine">
        <xsl:with-param name="variable1" select="@value1"/>
        <xsl:with-param name="variable2" select="path/node/@value2"/>
        <xsl:with-param name="variable3" select="path/node/@value3"/>
        <xsl:with-param name="variable4" select="@value4"/>
        <xsl:with-param name="variable5" select="@value5"/>
        <xsl:with-param name="variable6">value6</xsl:with-param>
</xsl:call-template>

在大多数模板中,我有超过 6 个参数。

我在另一个 xsl 文件中这样调用模板:

<xsl:template name="HostDefine">
    <xsl:param name="Variable1"/>
    <xsl:param name="Variable2"/>
    <xsl:param name="Variable3"/>
    <xsl:param name="Variable4"/>
    <xsl:param name="Variable5"/>
    <xsl:param name="Variable6"/>
</xsl:template>

现在在关闭模板之前,我想以这种方式将所有变量打印到新文件中:

o=<xsl:value-of select="$Variable1"/>
p=<xsl:value-of select="$Variable2"/>
q=<xsl:value-of select="$Variable3"/>
r=<xsl:value-of select="$Variable4"/>
s=<xsl:value-of select="$Variable5"/>
t=<xsl:value-of select="$Variable6"/>

这就是我的结构。我现在的问题是,其中一些变量可能为空。每当它们为空时,不应打印它们(也不应打印“o = / p = / q = / ...”。所以我需要在模板内的某个地方询问变量是否有值或是否为空(空 = '')。

首先我想用“for-each”来做,但我意识到我只能用节点做这个。比我想到的一种 for 循环(或在 xslt 中的增量调用),但是我不能循环遍历不同的参数。因此,我目前看到的唯一方法是在每个变量之前进行 if 调用,以查看它是否为空。但是有时一个模板中有超过 20 个变量和大约 10 个模板,这将是一件非常巨大的事情。有没有更优雅/更好的方法来做到这一点?

【问题讨论】:

  • 定义“空”。如果您有&lt;xsl:with-param name="variable1" select="@value1"/&gt;,那么如果上下文元素没有value 属性,则结果可以是空节点集(XSLT 1.0)或序列(XSLT 2.0),或者可以是具有单个属性节点的节点集或序列。在这种情况下,您可以随时检查boolean($variable1) 以检查节点集或序列是否不为空。但是 value6 不同,你设置的值是结果树片段或者临时树。
  • 如果它为空,则 xml 文件中的节点中没有“值”属性。但是,只要 xml 文件的节点中没有“值”属性,手动将其设置为空字符串或只是一个空白 ('') 不会有问题。我的目标是创建干净且结构化的代码。我可以走任何看起来不错的路。这是否回答了这个问题。我不确定我是否完全明白了。
  • 是 XSLT 1.0 还是 2.0?您是否总是传递所有声明的参数,或者您的声明“在大多数模板中,我有超过 6 个参数”表明您可能声明了超过 6 个参数,但有时传递的参数少于声明的参数?
  • 我使用 XSLT 1.0。我每次都将相同数量的参数传递给一个模板(所有为该模板声明的参数)。我想说的是,我有不同类型的模板和不同数量的参数,我传递给这些模板。但是对于一个模板,我每次都传递相同数量的参数

标签: xml xslt


【解决方案1】:

如果我们在 XSLT 1.0 中讨论传递节点集,那么您可以声明 &lt;xsl:param name="param-name" select="/.."/&gt; 以确保默认值为空节点集,然后您可以检查

<xsl:if test="$param-name">
  ... = <xsl:value-of select="$param-name"/>
</xsl:if>

检查是否已通过非空节点集。

该方法适用于所有前五个示例,其中您使用带有 XPath 表达式选择节点的 select 属性定义传递的参数值。

对于带有&lt;xsl:with-param name="variable6"&gt;value6&lt;/xsl:with-param&gt; 的示例,您传递了一个永远不会为空的结果树片段,因此boolean($variable6) 检查不适用于该方法。

【讨论】:

  • 所以在从模板调用 (&lt;xsl:param name="Variable1"/&gt;) 移交变量之前,您将在模板 (name="HostDefine) 内部进行声明 (&lt;xsl:param name="param-name" select="/.."/&gt;)?围绕每一行 ( o=&lt;xsl:value-of select="$Variable1"/&gt;) 你会放置 。我认为这是一个非常不雅且大的选项,但如果你说这是一个好方法,我会这样尝试。
  • 必须在模板内部声明参数,我没有看到不声明参数就可以使用参数的方法。我不知道您是否需要所有这些参数和命名模板,您还没有显示任何输入样本,任何具体的模板调用。我当然不会为所有这些属性选择使用参数select="@value1",我会根据需要简单地选择模板中的属性,只要不同节点不需要不同的选择即可。
  • 谢谢。我想了很久,因为我的情况很混乱,因为我需要检查大量数据(至少对我来说是这样)。我尝试了用默认值声明它的建议。 select="/.." 对我不起作用,但 select="''" 是可能的。我仍在考虑如何管理参数(我数了一下,在一个模板中它必须超过 45 个参数)。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-27
  • 1970-01-01
  • 2017-03-29
  • 2017-08-31
  • 1970-01-01
相关资源
最近更新 更多