2010-10-05 19 views
1

我真的不能制定更好,所以我會用,而不是一個例子去:如何根據與我正在搜索的樹中的屬性具有相同名稱的屬性,在循環中使用xpath獲取XML節點?

XML:

<root> 
    <foo> 
    <bar id="1">sdf</bar> 
    <bar id="2">sdooo</bar 
    </foo> 
    <feng> 
    <heppa id="4">hihi</heppa> 
    <heppa id="2">sseeapeea</heppa> 
    <heppa id="1">....</heppa> 
    </feng> 
</root> 

XSLT:

<xsl:for-each select="/root/foo/bar"> 
    <p> 
    <xsl:value-of select="." />: <xsl:value-of select="/root/feng/heppa[@id = @id]" /> 
    </p> 
</xsl:for-each> 

所需的輸出:

<p>sdf: ....</p> 
<p>sdooo: sseeapeea</p> 

實際產量:

<p>sdf: hihi</p> 
<p>sdooo: hihi</p> 
+0

無論何時您有交叉引用,都應該使用密鑰。檢查我的答案。 – 2010-10-05 13:53:49

回答

3

對於使用XPath 1.0選擇節點而已,你需要做的一個節點集比較:

/root/feng/heppa[@id=/root/foo/bar/@id] 

當然,這有N×M的複雜性(如其他XSLT解決方案)

使用XSLT 1.0你應該使用密鑰,因爲存在交叉引用:

<xsl:key name="kBarById" select="bar" use="@id"/> 

<xsl:template match="/root/feng/heppa[key('kBarById',@id)]">  
    <p>  
     <xsl:value-of select="concat(key('kBarById',@id),': ',.)"/> 
    </p>  
</xsl:template> 
+0

+1關鍵'解決方案! – 2010-10-05 18:01:24

+0

+1以獲得良好的解決方案。 「當然,這具有NxM複雜性:這取決於處理器。 key()是處理器如何優化的一個提示。處理器可以非常聰明,這樣沒有key()的樣式表可以像key()那樣有效地處理(或者換句話說,推斷出一個鍵)。但同意明確的key()解決方案更有效率。 – LarsH 2010-10-06 21:37:28

+0

@LarsH:我認爲推斷出的按鍵是在黑暗中拍攝的...節點集合比較更可能被認爲是優化的(突破第一次成功時的迭代),但我認爲它絕不會是線性N複雜度。 – 2010-10-06 21:56:12

2

我假設你的意思是/root/foo/bar因爲/root/foo元素沒有id。

您正在比較@id與自身,所以當然對於第一個節點檢查是正確的。可以使用current()來引用當前節點中的表達式:

<xsl:for-each select="/root/foo/bar"> 
    <p> 
    <xsl:value-of select="." />: <xsl:value-of select="/root/feng/heppa[@id = current()/@id]" /> 
    </p> 
</xsl:for-each> 
+0

是的,ofc!謝謝你的糾正。 :) 並非常感謝解決方案! :D – Lilleman 2010-10-05 13:00:31

1

另一種解決方案是讀取id屬性到一個變量。

<xsl:for-each select="/root/foo/bar"> 
    <xsl:variable name="id" select="@id"/> 
    <p> 
     <xsl:value-of select="." />: <xsl:value-of select="/root/feng/heppa[@id = $id]" /> 
    </p> 
</xsl:for-each> 

這可能是更加便利,如果你的實際使用情況更復雜,你需要使用id多次的價值在本作中,每個部分。

+0

非常好,沒想到那個。謝謝! – Lilleman 2010-10-05 13:12:49

相關問題