2010-07-16 17 views
0

我有下面的XML:計數不同的項目在XSLT和上市只有一次

<assessment> 
    <section> 
     <item> 
      <attributes> 
       <variables> 
        <variable> 
         <variable_name value="MORTIMER"/> 
        </variable> 
       </variables> 
      </attributes> 
     </item> 
     <item> 
      <attributes> 
       <variables> 
        <variable> 
         <variable_name value="FRED"/> 
        </variable> 
       </variables> 
      </attributes> 
     </item> 
     <item> 
      <attributes> 
       <variables> 
        <variable> 
         <variable_name value="MORTIMER"/> 
        </variable> 
       </variables> 
      </attributes> 
     </item> 
    </section> 
</assessment> 

我有以下XSLT來處理XML:

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

<xsl:key name="kValueByVal" match="item//variables//variable_name" 
      use="@value"/> 

<xsl:template match="assessment"> 
    <xsl:for-each select=" 
     .//item//variables//variable_name/@value 
     "> 
     <xsl:value-of select= 
     "concat(., ' ', count(key('kValueByVal', .)), '&#xA;')"/> 
     <br/> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

它輸出以下,這幾乎是我想要的:

MORTIMER 2 
FRED 1 
MORTIMER 2 

它列出了每個variable_names以及每次發生的次數。唯一的問題是,每次發生variable_name時,它只會給這個計數一次,而不是隻發生一次。

這就是我希望它輸出:

MORTIMER 2 
FRED 1 

如何修改XSLT代碼給我嗎?請注意,我們正在使用XSLT 1.0。

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

<xsl:key name="kValueByVal" match="item//variables//variable_name" 
      use="@value"/> 

<xsl:template match="assessment"> 
    <xsl:for-each select=".//item//variables//variable_name/@value[generate-id() 
                    = 
                    generate-id(key('kValueByVal',.)[1])]"> 
     <xsl:value-of select= 
     "concat(., ' ', count(key('kValueByVal', .)), '&#xA;')"/> 
     <br/> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 
+0

我的答案提供了一個短期的解決方案。 – 2010-07-16 18:35:52

回答

2

你真的需要了解Muenchian分組是如何工作的,否則你會永遠問相同問題的變化。

請仔細閱讀Jeni Tennison's tutorial

這裏是您的最新問題的解決方案:

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

<xsl:key name="kVarNameByVal" match="variable_name" 
      use="@value"/> 

<xsl:template match= 
    "variable_name[generate-id() 
       = 
       generate-id(key('kVarNameByVal', @value)[1]) 
       ] 
    "> 
     <xsl:value-of select= 
     "concat(@value, ' ', count(key('kVarNameByVal', @value)), '&#xA;')"/> 
     <br/> 
</xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔進行這種轉變,想要的結果產生:

MORTIMER 2 
FRED 1 
+0

我終於開始閱讀該教程,謝謝!現在我終於開始明白這個東西了。 – 2010-07-19 15:09:42

1

看到,因爲你正在使用XSLT 2.0,我會使用內置的grouping features

下面的解決方案,這似乎像它應該工作,沒有輸出。 (對於早期版本,你可能想看看Muenchian分組的)

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

<xsl:key name="kValueByVal" match="item//variables//variable_name" 
      use="@value"/> 

<xsl:template match="assessment"> 
    <xsl:for-each-group select=".//item//variables//variable_name" group-by="@value"> 
       <xsl:value-of select="concat(current-grouping-key(), ' ', count(current-group()), '&#xA;')"/> 
     <br/> 
    </xsl:for-each-group> 
</xsl:template> 
</xsl:stylesheet> 
+0

謝謝,但我嘗試時遇到以下錯誤: 「XSLT轉換期間出錯:XSLT轉換失敗。」 – 2010-07-16 15:57:06

+0

這些是我得到的錯誤: D:\ software \ source \ applications \ Athena \ main \ src \ vue \ exam \ inspector \ xslt> xalan repository.inspection -pi.xml variables.xslt XSLT警告: xsl:for-each-group是一個未知的XSLT元素。 (variables.xslt,第11行,第87列。) XPathParserException:未找到函數'current-grouping-key'。表達式='concat(current-grouping-key(),'',count(current-group()),' ')'剩餘的令牌是:('current-grouping-key''('')'' ('''''''','''' '''')')(variables.xslt,line 12,列110) – 2010-07-16 16:06:01

+0

也許處理器真的不是2.0。有沒有1.0解決方案? – 2010-07-16 16:10:22

1

你得到你所要求的:

<xsl:for-each select=".//item//variables//variable_name/@value"> 

至極的意思是:這些屬性的每一個

分組時,你必須說:一類的其中之一的每一個

而且,你怎麼知道這是獨一無二的?用Muenchian方法:

<xsl:for-each select=".//item//variables//variable_name/@value[generate-id() 
                   = 
                   generate-id(key('kValueByVal',.)[1])]"> 

這意味着:那些是那個關鍵字的第一個。

編輯:此外,當你知道輸入模式時,請避免//

編輯:現在我可以看到你改變了密鑰...所以,對於你來說新密鑰,誰是第一個?是! variable_name元素:

<xsl:for-each select=".//item//variables//variable_name[generate-id() 
                 = 
                 generate-id(key('kValueByVal',@value)[1])]"> 
+0

我自己試過,但那不是輸出任何東西。 – 2010-07-16 16:22:09

+0

@Paul Reiners:那是因爲你改變了鑰匙。在你對許多關於同樣的樣式表的問題上做了小小的改變之後,它是非常困難的。 – 2010-07-16 17:05:22

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

<xsl:key name="kValueByVal" match="item//variables//variable_name" 
      use="@value"/> 

<xsl:template match="assessment"> 
    <xsl:for-each 
       select="//item//variables//variable_name[ 
          generate-id() = 
           generate-id(key('kValueByVal', @value)[1])]"> 
     <xsl:value-of select= 
     "concat(./@value, ' ', count(key('kValueByVal', ./@value)), '&#xA;')"/> 
     <br/> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 
1

這將做它在XSLT 1.0。

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

<xsl:key name="kValueByVal" match="item//variables//variable_name" 
      use="@value"/> 

<xsl:template match="assessment"> 
    <xsl:for-each select=" 
     //item//variables//variable_name[not(@value=ancestor::item/preceding-sibling::item//variables//variable_name/@value)] 
     "> 
     <xsl:value-of select= 
     "concat(@value, ' ', count(key('kValueByVal', @value)), '&#xA;')"/> 
     <br/> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

我得到的輸出是

MORTIMER 2 
<br />FRED 1 
<br /> 

注意,它假定更多的有關文檔結構的(祖先::項目位),但你應該能夠把它從那裏。