2013-12-21 71 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