在下一次迭代中显示为NodeSet的字符串 - XSLT

时间:2011-10-07 05:19:02

标签: xslt recursion

这一定很容易,但我无法弄清楚。

如果'95'之前的子串长度为偶数,则目标是将'95'替换为'3F'。如果'95'之前的子串长度不是偶数,则将子串的值与'95'中的值'9'一起取出,并再次递归地查找95的出现以替换该值。

最终字符串的值将替换为'3F'

将字符串值分配给'inputHex'变量。将相同的内容传递给'inputHexStr'以调用模板replace95。在给定的字符串中,第一个值'95'出现在位置134和135处。因此条件不是(字符串长度(substring-before($ inputHexStr,$ from))mod 2 = 0)被调用。问题是......在下一次使用字符串的剩余值调用'replace95'模板时,该字符串不可访问,调试显示为节点集。

为什么?

更新 - 输入xml为<x/>,下一次迭代正在将上下文更改为给定xml文件的根节点,inputHexStr的值显示为nodeset而不是string。

 <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="text"/>
    <xsl:template match="/">
        <xsl:variable name="inputHex"
            select="'3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D227574662D3822203F3E3C783E74686973206973206120626164206368617261637465722019520737472696E6720646174613C2F7895'"/>
        <xsl:variable name="hexResult">
            <xsl:call-template name="replace95">
                <xsl:with-param name="inputHexStr" select="$inputHex"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:value-of select="$hexResult"/>
    </xsl:template>
    <xsl:template name="replace95">
        <xsl:param name="inputHexStr" select="."/>
        <xsl:param name="from" select="'95'"/>
        <xsl:param name="to" select="'3F'"/>
        <xsl:choose>
            <xsl:when test="not(contains($inputHexStr,$from))">
                <xsl:value-of select="$inputHexStr"/>
            </xsl:when>
            <xsl:otherwise>

                <xsl:if test="string-length(substring-before($inputHexStr,$from)) mod 2 = 0">
                    <xsl:value-of select="substring-before($inputHexStr,$from)"/>
                    <xsl:value-of select="$to"/>
                    <xsl:call-template name="replace95">
                        <xsl:with-param name="inputHexstr"
                            select="substring-after($inputHexStr,$from)"/>
                        <xsl:with-param name="from" select="$from"/>
                        <xsl:with-param name="to" select="$to"/>
                    </xsl:call-template>
                </xsl:if>
                <xsl:if test="not(string-length(substring-before($inputHexStr,$from)) mod 2 = 0)">
                    <xsl:variable name="no95part"
                        select="substring($inputHexStr,1,string-length(substring-before($inputHexStr,$from))+1)"/>
                    <xsl:value-of select="$no95part"/>

                    <xsl:variable name="no95Length" select="string-length($no95part)"/>

                        <xsl:call-template name="replace95">
                            <xsl:with-param name="inputHexstr" select="substring($inputHexStr,$no95Length+1)"/>
                            <xsl:with-param name="from" select="$from"/>
                            <xsl:with-param name="to" select="$to"/>
                        </xsl:call-template>

                </xsl:if>

            </xsl:otherwise>
        </xsl:choose>


    </xsl:template>

</xsl:stylesheet>

1 个答案:

答案 0 :(得分:1)

我认为这是因为当您递归调用带参数的模板时会出现拼写错误。

<xsl:with-param name="inputHexstr" select=...

这里有一个小写 s 。 XSLT区分大小写,因此它应该是大写字母S

<xsl:with-param name="inputHexStr" select=...

请注意,可能值得将两个 xls:if 语句合并为一个 xsl:choose 以避免对余数进行额外计算

<xsl:choose>
   <xsl:when test="not(contains($inputHexStr,$from))">...</xsl:when>
   <xsl:when test="string-length(substring-before($inputHexStr,$from)) mod 2 = 0">...</xsl:when>
   <xsl:otherwise>...</xsl:otherwise>
</xsl:choose>