2013-07-17 28 views
0

現在我有XSLT,它可以按照我想要的方式轉換XML。但它運行速度很慢。主要的問題是在這裏:可能的XSLT優化

<xsl:key name="document" match="/coverage/module/method/seqpnt/@document" use="." /> 
<xsl:key name="classes" match="/coverage/module/method/@class" use="." /> 
<xsl:template match="/coverage[@profilerVersion='1.5.8 Beta']"> 

<xsl:variable name="allDocuments" select="module/method/seqpnt/@document[generate-id() 
            = generate-id(key('document',.)[1])]" /> 
    <xsl:for-each select="$allDocuments"> 
         <xsl:if test="$docUrl = ."> 

          <xsl:variable name="docId" select="position()" /> 


        ...... 
         <xsl:text>&#xa;</xsl:text> 
         </xsl:if> 
    </xsl:for-each> 

Basicly allDocuments變量包含的所有文件的列表 - 字符串列表。我想稍後將包含該文檔的值的輸入XML中的屬性替換爲文檔ID - 此列表中的絕對位置。現在我正在循環每個記錄並檢查字符串是否與列表中的字符串相同,如果是這樣 - 獲取位置。有什麼辦法可以獲得更好的表現嗎?例如在變量上使用鍵?

回答

0

您可以嘗試這樣的事:
加入其中基於一個唯一的ID連續基於xsl:numberkey()的模板。

<xsl:template match="seqpnt" mode="genId"> 
    <xsl:number count="/coverage/module/method/seqpnt[generate-id()=generate-id(key('kDocument',@document)[1])]" 
     level="any" /> 
</xsl:template> 

有了針對文檔屬性的父節點的關鍵:

<xsl:key name="kDocument" match="/coverage/module/method/seqpnt" use="@document" /> 

比你模板可以是這個樣子:

<xsl:template match="/coverage[@profilerVersion='1.5.8 Beta']"> 
    <!-- docUrl --> 
    <xsl:apply-templates select="key('kDocument',$docUrl)[1]" mode="genId" /> 
    <xsl:text>&#xa;</xsl:text> 
</xsl:template>