2010-04-29 83 views
5

好吧,我有這個XMLXSL唯一值

<roots> 
<root> 
    <name>first</name> 
    <item type='test'><something>A</something></item> 
    <item type='test'><something>B</something></item> 
    <item type='test'><something>C</something></item> 
    <item type='test'><something>A</something></item> 
    <item type='other'><something>A</something></item> 
    <item type='test'><something>B</something></item> 
    <item type='other'><something>D</something></item> 

</root> 
<root> 
<name>second</name> 
    <item type='test'><something>E</something></item> 
    <item type='test'><something>B</something></item> 
    <item type='test'><something>F</something></item> 
    <item type='test'><something>A</something></item> 
    <item type='other'><something>A</something></item> 
    <item type='test'><something>B</something></item> 
    <item type='other'><something>D</something></item> 

</root> 

</roots> 

現在我需要得到各根節點的唯一值到目前爲止,我已經

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output indent="yes" method="text"/> 
    <xsl:key name="item-by-value" match="something" use="."/> 
    <xsl:key name="rootkey" match="root" use="name"/> 

    <xsl:template match="/"> 
    <xsl:for-each select="key('rootkey','second')"> 
     <xsl:for-each select="item/something"> 
     <xsl:if test="generate-id() = generate-id(key('item-by-value', normalize-space(.)))"> 
      <xsl:value-of select="."/> 
     </xsl:if> 
     </xsl:for-each> 
    </xsl:for-each> 
    </xsl:template> 

</xsl:stylesheet> 

如果我使用「第一」關鍵只得到第一根我得到一個好的結果ABCD

我怎麼過,如果我使用「第二」我只得到EF但需要得到的結果是ABDFE

+0

很好的問題(+1)。查看我的答案,獲得完整和正確的解決方案。 :) – 2010-04-30 01:04:05

回答

2

我得到EBFAD對你的xsl進行了一些修改。關鍵在於,如果您使用密鑰在給定根元素下查找包含此內容的第一個節點,則該密鑰需要特定於根元素。我改變了xsl:key到:

<xsl:key name="item-by-value" match="something" 
use="concat(normalize-space(.), ' ', generate-id(./ancestor::root))"/> 

然後xsl:if測試變爲:

<xsl:if test="generate-id() = generate-id(key('item-by-value', 
        concat(normalize-space(.), ' ', generate-id(./ancestor::root))))"> 
0

我覺得你很親密。但是,你只需要擁有正確的根作爲父項目按值鍵的第一個值:

<xsl:for-each select="key('rootkey','second')"> 
    <xsl:variable name="root" select="generate-id()" /> 
    <xsl:for-each select="item/something"> 
     <xsl:sort order="ascending" select="." data-type="text"/> 
     <xsl:if test="generate-id() = generate-id(key('item-by-value', .)[generate-id(ancestor::root)=$root][1])"> 
      <xsl:value-of select="."/> 
     </xsl:if> 
    </xsl:for-each> 
</xsl:for-each> 
+0

耶已經關閉了相當一段時間哈哈,即使與[1]我仍然得到相同的結果 – Nathan 2010-04-30 00:45:42

+0

有人試圖幫助時沒有必要是粗魯的。起初,我誤解了問題的「獨特」部分。我對代碼做了一些小修改以反映想要的結果。 – Lucero 2010-04-30 09:41:59

2

這是你必須使用一個複合鍵的情況。

該轉化

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 

<xsl:key name="kSomethingByNameAndVal" match="something" 
    use="concat(../../name, '+', .)"/> 

<xsl:template match="/"> 
    <xsl:for-each select="*/*"> 
    <xsl:for-each select= 
     "item/something 
      [generate-id() 
      = 
       generate-id(key('kSomethingByNameAndVal', 
           concat(../../name, '+', .) 
          ) 
         ) 
      ] 
     "> 

     <xsl:value-of select="."/> 
    </xsl:for-each> 
    <xsl:text>&#xA;</xsl:text> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔施加正確地產生希望的結果

ABCD

EBFAD