XSLT 1.0 Группировка по значениям узлов с одинаковыми именами на одном уровне, но с разными значениями - PullRequest
0 голосов
/ 25 марта 2011

Я мог бы использовать некоторую помощь.

Вот иллюстративный пример моего XML:

<items>
 <item>  
  <name>Thing 1</name>
  <colors>
    <color>white</color>
    <color>green</color>
  </colors>  
  </item>
 <item>  
  <name>Thing 2</name>
  <colors>
    <color>purple</color>
    <color>white</color>
    <color>black</color>  
  </colors>
 </item>
 <item>  
  <name>Thing 3</name>
   <colors/>
 </item>
</items>

Ниже приведена примерная версия моего xslt:

<xsl:key name="myGrouping" use="colors/color" match="item"/>  
<xsl:template match="/">
 <xsl:apply-templates select="items" mode="groupingTemplate"/>
</xsl:template>  

<xsl:template mode="groupingTemplate" match="items">  
 <xsl:for-each select="item[count(.|key('myGrouping',colors/color)[1])=1]">  
 <xsl:sort select="colors/color"/>  
 <xsl:if test="count(colors/color)&gt;0">
   <p><xsl:value-of select="colors/color"/></p>
   <xsl:for-each select="key('myGrouping',colors/color)">
   <xsl:sort select="name"/>
    <li><xsl:value-of select="name"/></li>
   </xsl:for-each>
  </xsl:if>
 </xsl:for-each>
</xsl:template>

Что я хочу сделать, так это сгруппировать в XSLT 1.0 (используя метод Мюнхена) по цветным узлам, поэтому мой вывод html будет:

<p>black</p>  
<li>Thing 2</li>  

<p>green</p>  
<li>Thing 1</li>  

<p>purple</p>  
<li>Thing 2</li>  

<p>white<p>  
<li>Thing 1</li>  
<li>Thing 2</li>  

Пока мой код может это делать, но забирает только первую запись. Другими словами, в приведенном выше примере мой вывод в настоящее время:

<p>white</p>
<li>Thing 1</li>
<li>Thing 2</li>

Помощь по решению и объяснение того, почему это происходит, будет принята с благодарностью.

Спасибо! Джефф

1 Ответ

2 голосов
/ 26 марта 2011

Понял это после долгих потягиваний волос ... следующий xsl делает трюк

<xsl:key name="byColor" use="." match="item/colors/color"/>  
<xsl:template match="/">
  <xsl:apply-templates select="items" mode="groupingTemplate"/>
</xsl:template>  

<xsl:template mode="groupingTemplate" match="items">  
  <xsl:for-each select="item/colors/color[count(.|key('byColor',.)[1])=1]">  
  <xsl:sort select="."/>  
  <xsl:if test="count(.)&gt;0">
    <p><xsl:value-of select="."/></p>
    <xsl:for-each select="key('byColor',.)">
     <xsl:sort select="../../name"/>
        <li><xsl:value-of select="../../name"/></li>
    </xsl:for-each>
   </xsl:if>
   </xsl:for-each>
 </xsl:template>
...