2012-06-18 80 views
1

我正在嘗試從XML中提取唯一值以及它們發生的次數。XSL分組計數

我一直在遵循Xslt distinct select/Group by給出的答案,但是我的模式有些不同。

我的XML看起來相似的東西:

<A> 
    <B> 
     <C> 
      <D>APPLE</D> 
     </C> 
    </B> 
    <B> 
     <C> 
      <D>BANANA</D> 
     </C> 
    </B> 
    <B> 
     <C> 
      <D>APPLE</D> 
     </C> 
    </B> 
</A> 

在以前的答案基於我的代碼有:

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

    <xsl:key 
    name="C-by-DValue" 
    match="B/C/D" 
    use="text()" 
    /> 

    <xsl:template match="A"> 
    <xsl:for-each select=" 
     B/C/D[ 
     count(
      . | key('C-by-DValue', B/C/D/text())[1] 
     ) = 1 
     ] 
    "> 
     <xsl:value-of select="text()"/> 
     <xsl:value-of select="' - '"/> 
     <!-- simple: the item count is the node count of the key --> 
     <xsl:value-of select=" 
     count(
      key('C-by-DValue', text()) 
     ) 
     "/> 
     <xsl:value-of select="'&#10;'"/> 
    </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

但這返回:

APPLE - 2 
BANANA - 1 
APPLE - 2 

所以對-each-select不僅與每個text()值的第一個實例相匹配。請有人指出我正確的方向。

回答

3

你想改變

<xsl:template match="A"> 
    <xsl:for-each select=" 
     B/C/D[ 
     count(
      . | key('C-by-DValue', B/C/D/text())[1] 
     ) = 1 
     ] 
    "> 
     <xsl:value-of select="text()"/> 
     <xsl:value-of select="' - '"/> 
     <!-- simple: the item count is the node count of the key --> 
     <xsl:value-of select=" 
     count(
      key('C-by-DValue', text()) 
     ) 
     "/> 
     <xsl:value-of select="'&#10;'"/> 
    </xsl:for-each> 
    </xsl:template> 

<xsl:template match="A"> 
    <xsl:for-each select=" 
     B/C/D[ 
     count(
      . | key('C-by-DValue',.)[1] 
     ) = 1 
     ] 
    "> 
     <xsl:value-of select="text()"/> 
     <xsl:value-of select="' - '"/> 
     <!-- simple: the item count is the node count of the key --> 
     <xsl:value-of select=" 
     count(
      key('C-by-DValue', text()) 
     ) 
     "/> 
     <xsl:value-of select="'&#10;'"/> 
    </xsl:for-each> 
2

有可能實現在更短的方式這個任務組,從來沒有使用xsl:for-each

這種轉變

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

<xsl:key name="kDByVal" match="D" use="."/> 

<xsl:template match="D[generate-id()=generate-id(key('kDByVal', .)[1])]"> 
    <xsl:value-of select= 
    "concat(., ' - ', count(key('kDByVal', .)), '&#xA;')"/> 
</xsl:template> 
<xsl:template match="text()"/> 
</xsl:stylesheet> 

時所提供的XML文檔應用:

<A> 
    <B> 
     <C> 
      <D>APPLE</D> 
     </C> 
    </B> 
    <B> 
     <C> 
      <D>BANANA</D> 
     </C> 
    </B> 
    <B> 
     <C> 
      <D>APPLE</D> 
     </C> 
    </B> 
</A> 

產生想要的,正確的結果

APPLE - 2 
BANANA - 1