2010-12-23 188 views
1

什麼是找到當前節點是否具有特定屬性的一個節點的路徑,給出這個XML結構的最快方法:檢查節點中的一個節點的路徑具有特定屬性的

<root> 
<item> 
    <item name="x"> 
     <item></item> 
     <item name="y"></item> 
     <item></item> 
    </item> 
    <item></item> 
    <item></item> 
</item> 
<item> 
    <item name="z"></item> 
    <item></item> 
</item> 

我有一個xslt變量來告訴我當前活動節點是什麼。

我想執行一些代碼,如果當前節點是在@name x節點的路徑中。

因此,如果活動節點是帶有@name y的項目,則代碼應該執行,如果當前活動節點是帶有@name z的項目,則不應該執行。

我最好的解決方案迄今:

ancestor-or-self::item[@name = 'x'] 

但因爲有這個正在採取永遠呈現30K +項目節點,有沒有更快的方法? (XSLT/XPATH 2不是選項)

+0

您的意思是XSLT/XPATH版本2.0不是一個選項,但XSLT/XPATH 1.0還行嗎? – khachik 2010-12-23 12:40:45

+0

@漢斯科夫:「祖先或自我」在表演中不應該那麼沉重。問題必須出現在您的轉換模式中:爲每個節點運行此應用程序應該具有性能成本。 – 2010-12-23 14:08:25

回答

2

最好的方法強烈依賴於整個轉換。

人們可以假設,模式匹配優化,所以:

<xsl:template match="item[@name='x']//*"> 

此外,您還可以使用這樣的模式:

<xsl:template match="item[@name='x']"> 
    <xsl:apply-templates mode="descandants-in-path"> 
</xsl:template> 

<xsl:template match="node()" mode="descandants-in-path"> 

或參數,如:

<xsl:template match="item[@name='x']"> 
    <xsl:apply-templates> 
     <xsl:with-param name="pIsInPath" select="true()"/> 
    </xsl:apply-templates> 
</xsl:template> 

<!-- Tunnel rule --> 
<xsl:template match="*"> 
    <xsl:param name="pIsInPath"/> 
    <xsl:apply-templates> 
     <xsl:with-param name="pIsInPath" select="$pIsInPath"/> 
    </xsl:apply-templates> 
</xsl:template> 
0

要添加到@Alejandro的好答案:

在完整的名稱,在XSLT一個可以定義一個關鍵

<xsl:key name="kInSubtreebyId" 
     match="item[ancestor-or-self::item[@name='x']]" 
     use="generate-id()"/> 

,然後引用該鍵像這樣

<xsl:if test="key('kInSubtreebyId', generate-id())"> 
. . . . . . . 
</xsl:if> 

從理論上說,使用這種關鍵的可能比其他方法更快,如果任何特定節點的測試執行(平均)超過一次。

但是,您可能需要大量的索引內存。

相關問題