2012-09-28 14 views
2

我有這樣的XML:XSL 「下面的」 返回沒有什麼預期

<ROWSET> 
    <ROW> 
     <FLD1>P2</FLD1> 
     <S_VAL>1</S_VAL>  
     <FLD2>N2</FLD2> 
    </ROW> 
    <ROW> 
     <FLD1>P3</FLD1> 
     <S_VAL>2</S_VAL> 
     <FLD2>N2</FLD2>  
    </ROW> 
    <ROW> 
     <FLD1>P3</FLD1> 
     <S_VAL>3</S_VAL> 
     <FLD2>N2</FLD2>  
    </ROW> 
    <ROW> 
     <FLD1>P4</FLD1> 
     <S_VAL>4</S_VAL>  
     <FLD2>N3</FLD2> 
    </ROW> 
    <ROW> 
     <FLD1>P2</FLD1> 
     <S_VAL>5</S_VAL>  
     <FLD2>N3</FLD2> 
    </ROW> 
    </ROWSET> 

,我已經在我的XSL 2個變量:

<xsl:variable name="only_need" select="/ROWSET/ROW[./FLD2='N2']"/> 
    <xsl:variable name="only_need2" select="$only_need/FLD1[not(.=following::FLD1)]"/> 

在名爲 「only_need」 我收到變量記錄與S_Val IN(1,2,3)。 但是在名稱爲「only_need2」的變量中,我只收到FLD1 = P3。 爲什麼第二個變量只接收FLD1 = P3的問題?

回答

0

這回答您的問題來自於好的答案由伊恩·羅伯茨評論:

你能告訴我,我怎麼能只有「only_need」

在使用「下面」的事實上,這是一個純粹的XPath問題。

可以避免使用鍵和只使用諸如「之前」或「之後」的軸來找到「不同」元素,但請記住,這是非常慢的 - O(N^2 )作爲comared使用鍵 - (O(N)):

<xsl:variable name="vOnlyNeed" select="/*/*[FLD2='N2']"/> 
<xsl:variable name="vOnlyNeedDistinct" select= 
    "$vOnlyNeed 
    [not(FLD1 
     = 
     following::* 
      [count(.|$vOnlyNeed) = count($vOnlyNeed)] 
      /FLD1)] 
    "/> 

下面是一個完整變換

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

<xsl:variable name="vOnlyNeed" select="/*/*[FLD2='N2']"/> 
<xsl:variable name="vOnlyNeedDistinct" select= 
    "$vOnlyNeed 
    [not(FLD1 
     = 
     following::* 
      [count(.|$vOnlyNeed) = count($vOnlyNeed)] 
      /FLD1)] 
    "/> 

<xsl:template match="/"> 
    <xsl:copy-of select="$vOnlyNeedDistinct"/> 
</xsl:template> 
</xsl:stylesheet> 

當該變換被施加到p規定外XML文檔

<ROWSET> 
    <ROW> 
     <FLD1>P2</FLD1> 
     <S_VAL>1</S_VAL> 
     <FLD2>N2</FLD2> 
    </ROW> 
    <ROW> 
     <FLD1>P3</FLD1> 
     <S_VAL>2</S_VAL> 
     <FLD2>N2</FLD2> 
    </ROW> 
    <ROW> 
     <FLD1>P3</FLD1> 
     <S_VAL>3</S_VAL> 
     <FLD2>N2</FLD2> 
    </ROW> 
    <ROW> 
     <FLD1>P4</FLD1> 
     <S_VAL>4</S_VAL> 
     <FLD2>N3</FLD2> 
    </ROW> 
    <ROW> 
     <FLD1>P2</FLD1> 
     <S_VAL>5</S_VAL> 
     <FLD2>N3</FLD2> 
    </ROW> 
</ROWSET> 

中的XPath表達式,並且所述如此定義的變量$vOnlyNeedDistinct的內容被複制到輸出

<ROW> 
    <FLD1>P2</FLD1> 
    <S_VAL>1</S_VAL> 
    <FLD2>N2</FLD2> 
</ROW> 
<ROW> 
    <FLD1>P3</FLD1> 
    <S_VAL>3</S_VAL> 
    <FLD2>N2</FLD2> 
</ROW> 
+0

只有10-15條記錄將在$ vOnlyNeed中。所有作品像你sed。但不完全清楚過濾器如何工作'[count(。| $ vOnlyNeed)= count($ vOnlyNeed)]' – user1705617

+0

訣竅是XPath在節點_sets_上工作,所以當你使用'exprA |兩個表達式匹配的exprB節點只計算一次。因此,當且僅當有問題的節點('.')是集合「$ vOnlyNeed」的成員時,'[count(。| $ vOnlyNeed)= count($ vOnlyNeed)]'才爲真。 –

+0

感謝您的詳細解答。 – user1705617

1

only_need2包含在FLD1了孩子們的行only_need其值不同於以下所有FLD1元素整個文檔中的,不只是在only_need不同。所以你沒有得到P2,因爲後面還有另一個P2(在第五行)。

如果你想要的其實是最後一排only_need爲每個不同的FLD1值,你可以做,用鑰匙

<xsl:key name="key_only_need2" match="/ROWSET/ROW[FLD2='N2']/FLD1" use="." /> 
<xsl:variable name="only_need2" select="$only_need/FLD1[ 
     generate-id() = generate-id(key('key_only_need2', .)[last()])]" /> 

我在做什麼這裏定義的關鍵是將提取來自FLD2N2的行的所有FLD1元素,並將它們按其FLD1值進行分組。變量聲明中的謂詞使用此鍵僅從這些組中的每個組中選擇最後一個元素。

+0

感謝。你能告訴我,我怎麼能使用「跟隨」只爲「only_need」 – user1705617

+0

好。感謝您的詳細解答。 – user1705617