XSL中的零宽度空间会导致stackoverflow错误



我使用的是FOP 1.1,我有一个文本最多可以包含20000个字符,由于文本之间不包含任何空格,我修改了xsl以使用零宽度空格。如果xml标记包含大约1500个字符,那么它就可以正常工作,如果超过1500个字符的话,我会得到堆栈溢出错误。weblogic服务器中的堆空间也是2GB。有人能提供一个可能的解决方案吗?或者xsl中是否有任何缺陷。

下面是xsl代码示例-

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:locale="xalan://java.util.Locale" 
xmlns:arrayList="xalan://java.util.ArrayList" 
xmlns:func="http://exslt.org/functions" extension-element-prefixes="func"
version="1.0">
..................


<fo:block>
<xsl:value-of select="func:callTemplate(summaryData)"/>
</fo:block>
..................
<xsl:template name="zero_width_space_1">
<xsl:param name="data"/>
<xsl:param name="counter" select="0"/>
<xsl:choose>
<xsl:when test="$counter &lt; (string-length($data))">
<xsl:value-of select='concat(substring($data,$counter,1),"&#8203;")'/>
<xsl:call-template name="zero_width_space_2">
<xsl:with-param name="data" select="$data"/>
<xsl:with-param name="counter" select="$counter+1"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="zero_width_space_2">
<xsl:param name="data"/>
<xsl:param name="counter"/>
<xsl:value-of select='concat(substring($data,$counter,1),"&#8203;")'/>
<xsl:call-template name="zero_width_space_1">
<xsl:with-param name="data" select="$data"/>
<xsl:with-param name="counter" select="$counter+1"/>
</xsl:call-template>
</xsl:template>

<func:function name="func:callTemplate">
<xsl:param name="string1"/>
<xsl:call-template name="zero_width_space_1">
<xsl:with-param name="data" select="$string1"/>
</xsl:call-template>
<func:result/>
</func:function>
</xsl:stylesheet>

下面是我得到的错误-

由以下原因引起:java.lang.StackOverflowErrororg.apache.xml.utils.FastStringBuffer.append(FastStringBuffer.java:499)在org.apache.xml.dtm.ref.dom2dtm.dom2dtm.getNodeData(dom2dtm.java:935)在org.apache.xml.dtm.ref.dom2dtm.dom2dtm.getNodeData(dom2dtm.java:928)在org.apache.xml.dtm.ref.dom2dtm.dom2dtm.getStringValue(dom2dtm.java:827)在org.apache.xpath.objects.XNodeSet.getStringFromNode(XNodeSet.java:217)在org.apache.xpath.objects.XNodeSet.xstr(XNodeSet.java:256)org.apache.xpath.functions.FunctionDef1Arg.getArg0AsString(FunctionDef1Arg.java:97)在org.apache.xpath.functions.FunccStringLength.execute(FuncStringLeng.java:45)在org.apache.xpath.Expression.execute(Expression.java:155)org.apache.xpath.operations.Opermission(Operation.java:110)org.apache.xpath.Expression.bool(Expression.java:186)org.apache.xpath.XXPath.bool(xpath.java:412)org.apache.xalan.templates.ElemChoose.execute(ElemChoose.java:126)org.apache.xalan.transformer.TransformerImpl.executeChildTemplate(TransformerImpl.java:2400)在org.apache.xalan.templates.ElemTemplate.execute(ElemTemplate.java:394)在org.apache.xalan.templates.ElemCallTemplate.execute(ElemCallTemplate.java:248)

我对这里需要两个模板感到困惑,因为你可以将逻辑组合成一个,就像一样

<xsl:template name="zero_width_space_1">
<xsl:param name="data"/>
<xsl:param name="counter" select="0"/>
<xsl:if test="$counter &lt;= (string-length($data))">
<xsl:value-of select='concat(substring($data,$counter,1),"&#8203;")'/>
<xsl:call-template name="zero_width_space_1">
<xsl:with-param name="data" select="$data"/>
<xsl:with-param name="counter" select="$counter+1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>

还要注意,你的函数不太正确,应该是这样的。。。

<func:function name="func:callTemplate">
<xsl:param name="string1"/>
<xsl:variable name="result">
<xsl:call-template name="zero_width_space_1">
<xsl:with-param name="data" select="$string1"/>
</xsl:call-template>
</xsl:variable>
<func:result select="$result" />
</func:function>    

我不确定这是否能解决您的堆栈溢出问题。但是,如果目的是在每个字符之前插入一个&#8203;,那么您可以使用exslt 中可用的tokenize函数

<func:function name="func:callTemplate">
<xsl:param name="string1"/>
<xsl:variable name="result">
<xsl:for-each select="str:tokenize($string1, '')">
<xsl:value-of select="concat('&#8203;', .)" />
</xsl:for-each>
<xsl:text>&#8203;</xsl:text>
</xsl:variable>
<func:result select="$result" />
</func:function>  

最新更新