2010-04-29 50 views
5

我有一些我想要使用xslt進行處理的xml。大量的數據通過關鍵值對傳遞(見下文)。我正在努力如何將密鑰的價值基礎提取到變量中。我希望能夠做到這樣的事情:我怎樣才能從我xslt xpath中的xml鍵/值對獲取值?

<xsl:variable name="foo" select="/root/entry[key = 'foo']/value"/> 

但這似乎並不奏效。這裏是示例xml。

<?xml version="1.0" encoding="ISO-8859-1"?> 
<root> 
    <entry> 
    <key> 
     foo 
    </key> 
    <value> 
     bar 
    </value> 
    </entry> 
</root> 

正確的xpath會是什麼?

+0

好問題(+1)。你知道你選擇的答案通常不正確嗎?請參閱我的回答以獲得解釋和兩個真正的解決方案。 :) – 2010-04-29 16:48:12

回答

5

以下轉化顯示了兩種方法來實現這一點 - 有和沒有使用<xsl:key>key()功能:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes"/> 

<xsl:key name="kValueByKey" 
    match="value" use="normalize-space(../key)"/> 

<xsl:template match="/"> 
    1. By key: <xsl:text/> 

    <xsl:copy-of select="key('kValueByKey', 'foo')"/> 

    2. Not using key: <xsl:text/> 

    <xsl:copy-of select="/*/*[normalize-space(key)='foo']/value"/> 
</xsl:template> 
</xsl:stylesheet> 

別注意,使用了normalize-space()功能的從的<key>值中去掉任何前導或尾隨空格字符。

+0

似乎是兩全其美的,對嗎? – TahoeWolverine 2010-04-29 17:20:04

+0

@TahoeWolverine:在純XPath中,*有*可以使用這個表達式。每當XPath由XSLT託管時,我總是更喜歡使用鍵 - 是不是很明顯,鍵表達式比「純粹的」XPath更簡單?支持密鑰的另一個非常有力的論據是,在大多數情況下,使用密鑰的速度要快很多。 – 2010-04-29 17:29:37

+0

是的,我現在明白了。我有點困惑,因爲我沒有看到你在哪裏定義變量。一旦我開始用這種方式創建變量,事情變得更加清晰。謝謝。 – TahoeWolverine 2010-04-29 17:47:31

4

你的XPath工作正常以下(等效)文件:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<root> 
<entry> 
    <key>foo</key> 
    <value> 
    bar 
    </value> 
</entry> 
</root> 

您可以使用XPath contains功能來獲得相同的結果,而不重組的XML:

<xsl:variable name="foo" select="/root/entry[contains(key,'foo')]/value"/> 
+0

我應該知道它會是這樣的。不幸的是,向創建xml的人解釋xml更改將非常困難。我將使用xpath。非常感謝。 – TahoeWolverine 2010-04-29 15:10:05

+0

非常直接的解決方案,但如果你的XML中的是'fooz',那麼它仍然包含'foo',並且你將會有錯誤的匹配。 – derloopkat 2013-12-12 10:14:16

2
<xsl:variable name="foo" select="/root/entry[key='foo']/value" /> 

這是完全匹配,從而確保有沒有多餘的空格或圍繞富新行字符在XML。否則use replace function和一個正則表達式來修剪它們。