无法在包含元素的子元素之后创建属性节点(过滤器)

时间:2013-05-31 21:34:51

标签: xslt

我有以下模板来传回过滤器属性:

<xsl:template name="have_arch_attrib">
<xsl:variable name="condition_values"/>
<xsl:variable name="security_values"/>
<xsl:variable name="arch_values"/>
<xsl:choose> 
    <xsl:when test=".[@arch]"> <!-- add arch values -->
        <xsl:variable name="arch_values" select=".[@arch]" />
    </xsl:when>

    <xsl:when test=".[@condition]"> <!-- Add condition values -->
        <xsl:variable name="condition_values" select=".[@condition]" />
    </xsl:when>

    <xsl:when test=".[@security]"> <!-- Add condition values -->
        <xsl:variable name="security_values" select=".[@security]"/>
    </xsl:when>
</xsl:choose>
<xsl:attribute name="filter"><xsl:value-of select="concat($condition_values, $security_values, $arch_values)"/></xsl:attribute>

我看过其他解决方案,但我看不出它们如何适用于此?

有人能给我一些线索吗?

谢谢,

拉​​斯

2 个答案:

答案 0 :(得分:2)

错误消息非常具有描述性 - 在添加任何子节点(元素,文本节点,注释或处理指令)后,无法使用<xsl:attribute>向元素添加属性节点。因此,导致该错误消息的问题是在您调用have_arch_attrib模板而不是模板本身之前发生的事情。

也就是说,你在这里给出的模板不会产生你想要的结果,因为你不能在创建XSLT变量后修改它的值。您需要重新构建模板以将<xsl:choose> 置于 <xsl:attribute>内,而不是尝试使用变量来携带各种值。或者实际上只是完全失去选择,因为要求value-of一个不存在的属性并不是一个错误,你只需要获得空字符串。

<xsl:attribute name="filter">
  <xsl:value-of select="@condition"/>
  <xsl:value-of select="@security"/>
  <xsl:value-of select="@arch"/>
</xsl:attribute>

答案 1 :(得分:1)

您的模板中存在一些问题。

  • 初始化后无法更改变量的值。
  • 您的测试条件错误。你应该看起来像 <xsl:when test="@arch">
  • 如果赋值变量只能用于第一个变量 现有属性将获得一个值,因为只有第一个部分时 将执行测试通行证。
  • 目标不明确是什么。

将模板解释为伪代码将是:属性过滤器应获取第一个现有属性的值(超出arch,条件或安全性)。 这将是这个xlst:

<xsl:template name="have_arch_attrib">
    <xsl:attribute name="filter">
    <xsl:choose>
        <xsl:when test="@arch">
            <xsl:value-of select="@arch" />
        </xsl:when>
        <xsl:when test="@condition">
            <xsl:value-of select="@condition" />
        </xsl:when>
        <xsl:when test="@security">
            <xsl:value-of select="@security" />
        </xsl:when>
    </xsl:choose>
    </xsl:attribute>
</xsl:template>

基于您对Ian Roberts答案的评论:
我检查属性是否存在的唯一原因是我需要用”,“来划分任何属性。我可以看到我如何能够改变这些属性

尝试这样的事情:

    <xsl:attribute name="filter">
            <xsl:if test="@arch">
                <xsl:value-of select="@arch" />
                <xsl:text>,</xsl:text>
            </xsl:if>
            <xsl:if test="@condition">
                <xsl:value-of select="@condition" />
                <xsl:text>,</xsl:text>
            </xsl:if>
            <xsl:if test="@security">
                <xsl:value-of select="@security" />
            </xsl:if>
    </xsl:attribute>
</xsl:template>

这仍然不完美,但你的陈述不够明确 如果“ delimit ”表示单独上述模板将生成一个未赢的终止逗号。为避免这种情况,您可以尝试:

 <xsl:template name="have_arch_attrib">
    <xsl:attribute name="filter">
        <xsl:for-each select="@arch | @condition | @security ">
            <xsl:value-of select="." />
            <xsl:if test="position() != last()" >
                <xsl:text>,</xsl:text>
            </xsl:if>
        </xsl:for-each>
        </xsl:attribute>
</xsl:template>