我正在尝试使用XSLT进行一些清理。我想对文本片段进行一些更改,并让所有其他节点保持平静。但是,我当前的实现运行速度非常慢,并消耗大量内存。删除小模板会将运行时间从一分钟更改为几分之一秒。
这是XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:import href="../common/identity.xsl"/>
<xsl:template match="text()" priority="100">
<xsl:variable name="pass1" select="replace(., '(_|~)', ' ')"/>
<xsl:variable name="pass2" select="replace($pass1, ' , ', ', ')"/>
<xsl:variable name="final" select="$pass2"/>
<xsl:value-of select="$final"/>
</xsl:template>
<xsl:template match="body/text()[1][. = ' '] | body/text()[last()][. = ' ']"
priority="200"/>
</xsl:stylesheet>
第一个模板替换了一些字符,第二个模板删除了第一个和最后一个文本片段,但前提是它们只包含一个空格(遗憾的是normalize-space
不符合我的需要)。
这个XSLT运行速度很慢,占用大量内存。如果我删除最后一个模板,则相同的XSLT运行速度很快,并使用正常的内存量。
XSLT使用Saxon-(HE | EE)9.5.1.3在oXygen 15.2中运行。
造成这种巨大性能损失的原因是什么?一般来说是否使用了文本片段?使用优先事项?使用[1]
和[last()]
?
答案 0 :(得分:3)
使用not(follow-sibling :: text())而不是last()修复它。你能解释一下为什么或给出一些指向last()的问题?
有两种评估模式的方法:从左到右,从右到左,对应于规范5.5.3节中给出的“正式”和“非正式”语义。从右到左的方法效率更高,但它不能用于所有模式;特别是,使用位置谓词的模式很棘手。 Saxon将有效地处理大量案件,包括match="para[last()]"
,但对于其他一些案件,包括match="para[last()-1]"
和(似乎)match="section/para[last()]"
,它需要缓慢而有条理的路线。我将看一下代码,看看是否可以改进。