2013-07-17 25 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>