如何在声明XSL变量时去除空格?

11

我需要创建一个带有choose的XSL变量,就像下面这样:

<xsl:variable name="grid_position">
  <xsl:choose>
    <xsl:when test="count(/Element) &gt;= 1">
      inside
    </xsl:when>
    <xsl:otherwise>
      outside
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>

然后在我的代码中,我进行了一个xsl if:

<xsl:if test="$grid_position = 'inside'">
   {...code...}
</xsl:if>

问题在于我的变量从来没有等于'inside',因为存在换行和缩进。我该如何从变量中删除空格?我知道可以使用disable-output-escaping="yes"在xsl:copy-of中使用时将其删除,但是在xsl:variable标签上不起作用。那么我应该如何删除这些空格和换行符?


不错的问题 (+1)。看看我的回答,里面有一个简短的一行XPath表达式适用于你的 <xsl:variable> :) - Dimitre Novatchev
4个回答

17

这就是 <xsl:text> 的作用:

<xsl:variable name="grid_position">
  <xsl:choose>
    <xsl:when test="count(/Element) &gt;= 1">
      <xsl:text>inside</xsl:text>
    </xsl:when>
    <xsl:otherwise>
      <xsl:text>outside</xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>

它允许您同时结构化代码和控制空格。

实际上,您应该避免在 XSL 中使用未包装在 <xsl:text> 中的文本节点,以避免将来出现这些类型的错误(即当代码重新格式化或重构时)。

对于像您的示例这样的简单情况,也可以执行Jim Garrison所建议的操作


另外,通过 count() 测试元素的存在是多余的。选择它就足够了,因为空节点集计算为 false

<xsl:when test="/Element">

嗯,这对于 <xsl:variable name="Params"> <xsl:for-each select="paramlists/list/param"> <xsl:value-of select="@name"/><xsl:text>:</xsl:text><xsl:value-of select="@value"/><xsl:text>;</xsl:text> </xsl:for-each> </xsl:variable> 这段代码也能很好地工作。 - zulucoda

5
最简单的方法是一开始就不要放置空格:
<xsl:variable name="grid_position">
  <xsl:choose>
    <xsl:when test="count(/Element) &gt;= 1">inside</xsl:when>
    <xsl:otherwise>outside</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

2
谢谢你的回答,但我选择了Tomalak的答案,因为我不希望我的代码在有人重新格式化XSL代码以添加换行符时出现错误。 - Gabriel
1
@Gabriel:你做得对。 Tomalak的答案更加通用。 - Jim Garrison

5
其他答案中的策略很好,实际上比这个更可取,如果可行的话。但是有时候你无法控制(或者更难控制)变量中的内容。在这种情况下,当你测试变量时,可以去除周围的空格:

不要使用:

<xsl:if test="$grid_position = 'inside'">

使用

<xsl:if test="normalize-space($grid_position) = 'inside'">

normalize-space()函数会去除前后空格,并将其他重复的空格合并成一个空格。


1
+1 这是迄今为止缺失的显而易见的答案。存储多余的空格,然后再次剥离它并不优雅,但有时候你无法避免这种情况,例如当你对 XML 没有影响力时。 - Tomalak

1

只需使用:

<xsl:variable name="grid_position" select=
 "concat(substring('inside', 1 div boolean(/Element)),
         substring('outside', 1 div not(/Element))
        )
 "/>

这是一个很好的技巧,点个赞。我经常会错过C/Java/JavaScript中的“?:”三目运算符。 - dolmen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接