XSLT / Xpath - 求和函数性能

时间:2013-12-21 12:07:06

标签: xslt xpath xslt-2.0 saxon xslt-3.0

我经常使用此xpath sum(preceding::*/string-length())

它完成我需要它做的事情(在XML文件中提供直到此上下文的所有文本的字符数)。

问题:它很慢。

我应该使用不同的内置功能吗?还是延期?

更新

根据Michael Kay的评论,我探讨了XSLT 3.0 <accumulator>。这是我第一次使用3.0(我必须更新OxygenXML以使其工作)。我还没有完全适应我的需要,但下面的初步测试显示了承诺。

<xsl:output method="xml" />

<xsl:accumulator 
    name="f:string-summ"
    post-descent="f:accum-string-length"
    as="xs:integer"
    initial-value="0">
    <xsl:accumulator-rule 
        match="text/*" 
        new-value="$value + string-length()"/>
</xsl:accumulator>

<xsl:template match="text/*">
        <xsl:value-of select="f:accum-string-length()" />
</xsl:template>

偏离主题:Stack Overflow需要一个“XSLT-3.0”标记。

2 个答案:

答案 0 :(得分:0)

我不认为sum函数速度慢,导航到所有前面的元素以及计算所有内容的字符串长度都很昂贵。至于优化它,你使用哪个XSLT 2.0处理器?

答案 1 :(得分:0)

如果在每个节点上调用此函数,那么样式表性能将为节点数量的O(n ^ 2)。

无论如何,该功能不正确。前面的轴为您提供父母的前一个兄弟姐妹以及您父母之前兄弟姐妹的子女,因此您堂兄弟的字符串长度不止一次。

尝试定义这样的备忘录函数:

<xsl:function name="f:preceding-string-length" saxon:memo-function="yes">
  <xsl:param name="n" as="element()"/>
  <xsl:sequence select="sum(ancestor::*/preceding-sibling::*[1]/(f:preceding-string-length(.) + string-length(.)))"/>
</xsl:function>

或者使用XSLT 3.0累加器,这完全相同。