XSLT:如何创建有条件地包含每个项目的项序列?



我想在 XSLT 2 中构造一个序列,其中序列的每个项目都单独有条件地包含。

像这样的东西(现实中的test表达式并不是微不足道的(:

<xsl:variable name="seq">
<xsl:if test="true()">
<xsl:value-of select="'foo'"/>
</xsl:if>
<xsl:if test="false()">
<xsl:value-of select="'bar'"/>
</xsl:if>
<xsl:if test="true()">
<xsl:value-of select="'baz'"/>
</xsl:if>
</xsl:variable>

在这种情况下,我希望变量seq值是序列('foo', 'baz')

但是,我似乎错过了一些东西,因为它没有按预期工作。我为上述返回的是一个带有单个项目的序列'foobar'(即应该是所有单个项目的字符串连接(。如果所有条件都为 false,我得到一个包含单个项目的序列,但该项目似乎是空字符串。

注意:令人困惑的是,我不认为<xsl:sequence>项必然与新序列的构建相关,因此与此用例无关。它似乎更多的是引用现有项目,而不是复制它们。

对于我现在尝试解决的特定用例的上下文:我正在尝试生成一个表示 HTML 类的字符串序列,每个字符串都以不同的布尔表达式为条件。这将生成一个可变长度的列表,介于 0 和多个字符串之间。然后,我计划将此列表序列化为空格分隔的字符串,正如 HTMLclass属性所期望的那样,如下所示:string-join($classes, ' ').

在尝试这个时,我最终找到了解决方案。您需要显式指定变量的类型为字符串序列!具体来说,我必须添加属性as="xs:string*".

生成的 XSLT 将变为:

<xsl:variable name="seq" as="xs:string*">
<xsl:if test="true()">
<xsl:value-of select="'foo'"/>
</xsl:if>
<xsl:if test="false()">
<xsl:value-of select="'bar'"/>
</xsl:if>
<xsl:if test="true()">
<xsl:value-of select="'baz'"/>
</xsl:if>
</xsl:variable>

有了这个,它按预期工作!在上面的情况下,我得到了('foo', 'baz')序列。当将所有条件更改为false()时,我得到了一个元素为零的序列。

您可以使用谓词来有条件地进行筛选:

<xsl:variable name="seq" as="xs:string*"
select="('foo', 'bar', 'baz')[position() = (1, 3)]"/>

例如,这里将选择序列的第一个和第三个元素,但重点是利用 XPath 的简洁、富有表现力而不是 XSLT 语句来陈述条件。

最新更新