1

我经常使用这个 xpathsum(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”标签。

4

2 回答 2

0

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

于 2013-12-21T12:24:00.850 回答
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 累加器,这几乎是一样的。

于 2013-12-21T15:18:14.057 回答