如何编写需要遍历列表的XSLT函数

时间:2019-12-22 12:20:51

标签: function xslt

我正在尝试编写一个XSLT函数,该函数检查定义允许角色的字符串与定义当前角色的字符串。两个字符串均包含以“:”分隔的列表的角色。问题是我不知道:

  • 如何正确定义函数的返回值
  • 如何在函数中正确使用for-each以动态分配值。

以下是我当前使用SAXON-9.9的尝试(无效)

<xsl:function name="acm:isMemberOf" as="xs:boolean">
    <xsl:param name="allowedRoles" as="xs:string"/>
    <xsl:param name="userRoles" as="xs:string"/>
    <xsl:variable name="pattern" select="':'"/>
    <xsl:for-each select="tokenize($userRoles,$pattern)">
        <xsl:variable name="userRole" select="."/>
        <xsl:if test="contains($allowedRoles,$userRole)">
            <xsl:value-of select="boolean('true')"/>
        </xsl:if>
    </xsl:for-each>
    <xsl:value-of select="boolean('false')"/>
</xsl:function>

1 个答案:

答案 0 :(得分:0)

您需要更详细地描述您的要求。对代码的要求进行逆向工程可能导致错误的假设。

但是,在我看来,您似乎正在尝试编写XSLT,就好像它是Java之类的过程语言一样,其中“ for”实际上是一个循环,您可以在找到匹配项时退出循环。对于像XSLT这样的功能语言,这完全是错误的方法。 xsl:for-each不是循环;它是一个映射表达式,将函数(指令的主体)应用于每个选定的项。

我怀疑您要执行的操作是:

<xsl:function name="acm:isMemberOf" as="xs:boolean">
    <xsl:param name="allowedRoles" as="xs:string"/>
    <xsl:param name="userRoles" as="xs:string"/>
    <xsl:sequence select="some $t in tokenize($userRoles, ':') 
                  satisfies contains($allowedRoles, $t)"/>
</xsl:function>

在您应该使用contains(x, y)的地方也可能使用x = y。这是一个令人惊讶的常见错误(我认为人们认为他们可以从其名称猜测功能的作用,这是一个危险的假设)。