【问题标题】:An attribute node (filter) cannot be created after a child of the containing element不能在包含元素的子元素之后创建属性节点(过滤器)
【发布时间】:2013-05-31 21:34:51
【问题描述】:

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

<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>

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

谁能给我一个线索?

谢谢,

罗斯

【问题讨论】:

    标签: xslt


    【解决方案1】:

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

    也就是说,您在此处给出的模板不会产生您想要的结果,因为您无法在创建 XSLT 变量后修改它的值。您将需要重新构建模板以将&lt;xsl:choose&gt; inside 放入&lt;xsl:attribute&gt;,而不是尝试使用变量来携带各种值。或者实际上完全失去选择,因为要求value-of 一个不存在的属性不是错误,您只需获得空字符串。

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

    【讨论】:

    • 我检查属性是否存在的唯一原因是我需要用“,”分隔任何属性。我可以看到我可以如何改变这些。再次感谢!
    • @RussUrquhart 如果您可以使用 XSLT 2.0,那么它变得非常简单:string-join((@condition, @security, @arch), ',')
    【解决方案2】:

    您的模板存在一些问题。

    • 初始化后变量的值不能改变。
    • 您的测试条件错误。你应该看起来像 &lt;xsl:when test="@arch"&gt;
    • 如果分配给变量只适用于第一个 现有属性将获得一个值,因为只有第一个 when 部分 with test pass 将被执行。
    • 不清楚您的目标是什么。

    将您的模板解释为伪代码将是:属性过滤器应获取第一个现有属性的值(超出拱门、条件或安全性)。 这将是这个 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>
    

    【讨论】:

    • 谢谢。这就是我在脑海中的看法,但在将其转换为 xslt 时仍然存在问题! fwiw,我有以下内容: Line of text 我想以 文本行我可以替换';',这是我遇到问题的其他属性的连接。谢谢你们!!!
    • 还假设拱门、条件和安全对于给定元素可以出现任何、全部或不出现。
    • 我不明白你的问题是什么。最后一个带有 for-each 的模板应该完全符合您的要求(除了将 ; 更改为 , 。你说你可以做到这一点。另外,直到知道你永远不会检查答案是否有效。看看faq 如果您不确定如何或何时。
    • 对不起,我不清楚。最后一个模板可以满足我的要求!如果有任何混淆,我只是想让我的例子更清楚。对不起,我产生了任何混乱,再次感谢!!!
    猜你喜欢
    • 1970-01-01
    • 2012-08-30
    • 1970-01-01
    • 2014-07-31
    • 2014-12-05
    • 1970-01-01
    • 1970-01-01
    • 2021-06-14
    相关资源
    最近更新 更多