XSLT错误:在子节点之后或生成元素之前,无法添加该属性;它会被忽略

时间:2015-10-26 20:07:57

标签: xml xslt xslt-1.0

XML:

       <xyz>
            <param name="test" value="center at &quot;St.&quot; francisco ">
       </xyz>

上面是我的XML,“XYZ”作为根标记。

以下是我的XSLT

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <!-- Identity transform -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>



    <xsl:template match="xyz">

        <vce>

            <xsl:apply-templates
                select="node()[not(self::added-source | self::param)] | @*" />

            <xsl:call-template name="param-template" />


            <added-sources>
                <xsl:for-each select="added-source">
                    <xsl:copy-of select="." />
                </xsl:for-each>
            </added-sources>
        </vce>

    </xsl:template>


    <xsl:template name="param-template">


        <xsl:for-each select="param">

            <xsl:variable name="paramNameValue">
                <xsl:value-of select="@name" />
            </xsl:variable>
            <xsl:variable name="paramValue">
                <xsl:value-of select="@value" />
            </xsl:variable>


            <xsl:choose>

                  <!--  When response has one line feeds --> 
                <xsl:when test="contains($paramValue, '&#10;')">

                    <xsl:variable name="modParamValue">
                        <xsl:call-template name="replace-string">
                            <xsl:with-param name="text" select="$paramValue" />
                            <xsl:with-param name="replace" select="'&#10;'" />
                            <xsl:with-param name="with" select="' '" />
                        </xsl:call-template>
                    </xsl:variable>

                    <xsl:call-template name="param-template" />

                    <param>
                        <xsl:attribute name="name">
                                 <xsl:value-of select="$paramNameValue" />
                              </xsl:attribute>
                        <xsl:attribute name="value">
                                 <xsl:value-of select="$modParamValue" />
                              </xsl:attribute>
                    </param>
                </xsl:when>



                <!--  when param value tag has quotes  -->
                <xsl:when test="contains($paramValue, '&quot;')">

                <xsl:variable name="modParamValue">
                        <xsl:call-template name="replace-string">
                            <xsl:with-param name="text" select="$paramValue" />
                            <xsl:with-param name="replace" select="'&quot;'" />
                            <xsl:with-param name="with" select="' '" />
                        </xsl:call-template>
                    </xsl:variable>
                     <xsl:call-template name="param-template" />
                       <param>
                     <xsl:attribute name="name">
                                 <xsl:value-of select="$paramNameValue" />
                              </xsl:attribute>
                        <xsl:attribute name="value">
                                 <xsl:value-of select="$modParamValue" />
                              </xsl:attribute>
                      </param>
                </xsl:when>




                <xsl:otherwise>
                    <xsl:copy-of select="." />
                </xsl:otherwise>

            </xsl:choose>

        </xsl:for-each>

    </xsl:template>

    <xsl:template name="replace-string">

        <xsl:param name="text" />
        <xsl:param name="replace" />
        <xsl:param name="with" />

        <xsl:choose>
            <xsl:when test="contains($text,$replace)">
                <xsl:value-of select="substring-before($text,$replace)" />
                <xsl:value-of select="$with" />
                <xsl:call-template name="replace-string">
                    <xsl:with-param name="text"
                        select="substring-after($text,$replace)" />
                    <xsl:with-param name="replace" select="$replace" />
                    <xsl:with-param name="with" select="$with" />
                </xsl:call-template>

            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$text" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

注意:

在我的XSLT中,我最初在搜索是否有换行符。如果有,那么我用白色空间替换。

我以同样的方式添加了新代码来搜索&quot;。如果我发现任何,我想用反斜杠引号(\“)替换它。

当我尝试执行此错误时,我得到了

错误:

在子节点之后或生成元素之前,不能添加属性“name”;它将被忽略。

有人可以让我知道我在做什么错误。

预期输出:

<xyz>
    <param name="test" value="center at \&quot;St.\&quot; francisco ">
 </xyz>

谢谢!

1 个答案:

答案 0 :(得分:1)

xsl:choose内,第一个xsl:when会创建param元素,然后创建namevalue属性。但是,第二个xsl:when尝试创建相同的属性,而不首先创建param元素。

因此,样式表尝试将这些属性分配给父节点(vce) - 但由于您的xsl:apply templates指令,该节点已经有了子节点。

加了:

要使用空格替换换行符并使用带有转义引号的引号,您只需执行以下操作:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="@value[contains(., '&quot;') or contains(., '&#10;')]">
    <xsl:attribute name="value">
        <xsl:call-template name="replace-string">
            <xsl:with-param name="text" select="translate(., '&#10;', ' ')" />
            <xsl:with-param name="replace" select="'&quot;'" />
            <xsl:with-param name="with" select="'\&quot;'" />
        </xsl:call-template>
    </xsl:attribute>
</xsl:template>

<xsl:template name="replace-string">
    <xsl:param name="text" />
    <xsl:param name="replace" />
    <xsl:param name="with" />
    <xsl:choose>
        <xsl:when test="contains($text,$replace)">
            <xsl:value-of select="substring-before($text,$replace)" />
            <xsl:value-of select="$with" />
            <xsl:call-template name="replace-string">
                <xsl:with-param name="text" select="substring-after($text,$replace)" />
                <xsl:with-param name="replace" select="$replace" />
                <xsl:with-param name="with" select="$with" />
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$text" />
        </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

</xsl:stylesheet>

测试输入:

<xyz>
    <param name="test" value="center at &quot;St.&quot; francisco&#10;second line"/>
</xyz>

<强>结果:

<?xml version="1.0" encoding="UTF-8"?>
<xyz>
  <param name="test" value="center at \&quot;St.\&quot; francisco second line"/>
</xyz>