2017-04-12 31 views
1

我有一個包含帶註釋的語音轉錄本的大型xml文檔。以下是一個簡短的片段。generate-id()對於大文檔來說太慢

<?xml version="1.0" encoding="UTF-8"?> 
<U> 
    <A/> 
    <C type="start" id="cb01s"/> 
    <P/> 
    <T>a</T> 
    <T>woman</T> 
    <P/> 
    <T>took</T> 
    <T>off</T> 
    <T>the</T> 
    <T>train</T> 
    <C type="end" id="cb02e"/> 
    <P/> 
    <T>but</T> 
    <P/> 
    <F/> 
    <RT> 
     <O> 
      <C type="start" id="cb03s"/> 
      <T>her</T> 
      <T>bag</T> 
      <P/> 
      <T>are</T> 
     </O> 
     <P/> 
     <E> 
      <C type="start" id="cb04s"/> 
      <T>her</T> 
      <T>bag</T> 
      <T>are</T> 
     </E> 
    </RT> 
    <P/> 
    <T>still</T> 
    <P/> 
    <T>in</T> 
    <T>the</T> 
    <T>train</T> 
    <C type="end" id="cb05e"/> 
    <PC>.</PC> 
</U> 

的基本任務,我需要做的是讓某些對<C>節點之間<T>節點的數量。我已經使用下面的樣式表片段來做到這一點(用一對特定的<C>節點來說明)。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text" encoding="UTF-8"/> 

    <xsl:template match="U"> 
     <xsl:variable name="start-node" select="descendant::C[@id = 'cb01s']"/> 
     <xsl:variable name="end-node" select="descendant::C[@id = 'cb02e']"/> 
     <xsl:text>Result: </xsl:text> 
     <xsl:value-of select="count($start-node/following::T[following::C[generate-id(.) = generate-id($end-node)]])"/> 
    </xsl:template> 

</xsl:stylesheet> 

這適用於諸如上述短XML片段罰款,並給出正確的結果:Result: 6

但是,實際的XML文檔包含成千上萬個節點<C>甚至更​​多<T>節點。所以當我嘗試在其上運行樣式表時,結果慢慢地返回非常。 (這可能需要幾天時間才能完成)。我想這個問題必須是在每次運行<xsl:value-of...行時,處理器(Saxon)正在檢查所有<T>節點併爲<C>節點生成id的倍數(即指數級)和這會降低一切。

有沒有辦法加快進程,同時仍然使用generate-id()?或者我需要使用一些替代方法來獲取<T>節點的數量?

+0

所有''是否屬於同一個''? – Tomalak

+0

是的。那將是最小的封裝節點。在大多數情況下,一個''節點可能由幾十個'節點組成。 – fildpauz

+1

是撒克遜9或6,或者你認爲你爲什麼需要生成id,並且它是性能問題的罪魁禍首。如果您使用Saxon 9,那麼問題來自代碼的配置文件(請參閱http://saxonica.com/html/documentation/using-xsl/performanceanalysis/)。當然,在XSLT 2中,檢查'following :: C [generate-id(。)= generate-id($ end-node)]'可以被寫爲'following :: C [1]'是$ end-node' 。對於其他方法,XSLT 2.0也具有'<<' and '>>'運算符和'對於每個組的組'開始/結束'。 –

回答

1

您不需要generate-id()只是爲了避免匹配<C>元素插入開始和結束節點之間。您首先匹配<C>元素的id屬性,我認爲沒有理由不直接使用它。例如,

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text" encoding="UTF-8"/> 

    <xsl:template match="U"> 
     <xsl:variable name="start-id" select="cb01s"/> 
     <xsl:variable name="end-id" select="cb02e"/> 

     <xsl:text>Result: </xsl:text> 
     <xsl:value-of select="count(descendant::C[@id = $start-id]/following::T[following::C[@id = $end-id][1]])"/> 
    </xsl:template> 

</xsl:stylesheet> 

您可以通過刪除[1]位置謂詞,如果你能依靠<C>元素@id使他能在文檔中獨一無二的簡化。

如果generate-id()確實是您的性能問題的主要原因,那麼完全避免它應該提供一個很大的提升。

相關問題