2013-12-21 43 views
1

我经常用这个XPath sum(preceding::*/string-length())XSLT/Xpath的 - 和功能性能

它做什么,我需要做的(提供的所有文字起来的字符计数来此背景下,XML文件中)。

问题:它很慢。

是否有不同的内置函数,我应该使用它?或者一个扩展?

UPDATE:

基于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”标签。

+0

您使用哪种Xslt解析器/编译器? – rene

+0

对于这一个..我使用Saxon HE,从命令行。 – Paulb

+0

你能指出你的xml的大小,当前时间和目标时间吗? – rene

回答

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蓄电池,其数额为同样的事情。

+0

XSLT 3.0累加器看起来像一个优雅的解决方案。我找到了W3规范并试用了它。带有SaxonPE 9.5.0.2的OxygenXML,出现错误消息“未知的系统功能累加器”。我读到的内容表明撒克逊人应该有累积器......它活着吗? – Paulb

+0

Saxon 9.5实现了2012年7月XSLT 3.0草案中描述的累加器。 2013年12月草案中的设计有所变化。 –

0

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

+0

对于这一个..我使用Saxon HE,从命令行。 – Paulb

+0

Saxon允许您分析样式表,请参阅http://saxonica.com/documentation/html/using-xsl/performanceanalysis.html。无论这对你的代码有帮助,我都不确定。在你对Rene的评论中,你还指出你的完整样式表很简短,所以考虑在你的问题中展示它,以及显示你需要处理的结构的输入示例,然后也许别人可以提出关于如何优化Saxon的XSLT的建议或一般。 –

+0

感谢Martin的想法。试过了......它告诉我迈克尔凯带来的明显(他用后视无价的智慧说)..看到他的回答。现在我认识到我的一些文档的大小,从1 MB到最大70 MB,我需要一种从流处理中受益的方法。 – Paulb