使用属性进行XSL分组

时间:2013-01-09 11:00:59

标签: xslt xslt-1.0

我有一些看起来像这样的XML:

<Options>
  <Option OptionGroup="Safety">Driver Airbag</Option>
  <Option OptionGroup="Comfort and Convenience">Front Electric Windows</Option>
  <Option OptionGroup="Comfort and Convenience">Height Adjustable Drivers Seat</Option>
  <Option OptionGroup="Comfort and Convenience">Pollen Filter</Option>
  <Option OptionGroup="Comfort and Convenience">Privacy Glass</Option>
  <Option OptionGroup="Comfort and Convenience">Remote Boot Release</Option>
  <Option OptionGroup="Comfort and Convenience">Split Rear Seats</Option>
  <Option>Something else</Option>
  <Option>Yet another thing</Option>
  <Option OptionGroup="Paint or Trim and Upholstery">Metallic Paint</Option>
  <Option OptionGroup="Exterior Equipment">Power Assisted Steering (PAS)</Option>
  <Option OptionGroup="Interior Equipment">Leather Steering Wheel</Option>
  <Option OptionGroup="In Car Entertainment">CD Radio</Option>
  <Option OptionGroup="Security">Central Locking</Option>
</Options>

我想使用XSL 1.0将输出分组,基于它们的OptionGroup attirbute,具有任何没有在末尾列出属性的选项。类似的东西:

<table>
<tr><th>Safety</th></tr>
  <tr><td>Drivers Airbag</td></tr>
<tr><th>Comfort and Convenience</th></tr>
  <tr><td>Front Electric Windows, Height Adjustable Drivers Seat, Pollen Filter, Privacy Glass, Remote Boot Release, Split Rear Seats</td></tr>
<tr><th>Paint or Trim and Upholstery</th></tr>
  <tr><td>Metallic Paint</td></tr>
<tr><th>Exterior Equipment</th></tr>
  <tr><td>Power Assisted Steering (PAS)</td></tr>
<tr><th>Interior Equipment</th></tr>
  <tr><td>CD Radio</td></tr>
<tr><th>Security</th></tr>
  <tr><td>Central Locking</td></tr>
<tr><th>Other</th></tr>
  <tr><td>Something else, Yet another thing</td></tr>
</table>

我猜这是可能的,但无法解决。非常感谢任何帮助。

感谢。

2 个答案:

答案 0 :(得分:1)

这是grouping sample

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

<xsl:param name="default" select="'Other'"/>

<xsl:output method="html" indent="yes"/>

<xsl:key name="ogroup" match="Option" use="string(@OptionGroup)"/>

<xsl:template match="Options">
  <table>
    <xsl:apply-templates select="Option[@OptionGroup][generate-id() = generate-id(key('ogroup', string(@OptionGroup))[1])]" mode="term"/>
    <xsl:apply-templates select="key('ogroup', '')[1]" mode="term"/>
  </table>
</xsl:template>

<xsl:template match="Option" mode="term">
  <tr>
    <th>
      <xsl:choose>
        <xsl:when test="@OptionGroup">
          <xsl:value-of select="@OptionGroup"/>
        </xsl:when>
        <xsl:otherwise><xsl:value-of select="$default"/></xsl:otherwise>
      </xsl:choose>
     </th>
     <td>
      <xsl:apply-templates select="key('ogroup', string(@OptionGroup))"/>
     </td>
   </tr>
</xsl:template>

<xsl:template match="Option">
  <xsl:if test="position() &gt; 1">, </xsl:if>
  <xsl:value-of select="."/>
</xsl:template>

</xsl:stylesheet>

它转换

<Options>
  <Option OptionGroup="Safety">Driver Airbag</Option>
  <Option OptionGroup="Comfort and Convenience">Front Electric Windows</Option>
  <Option OptionGroup="Comfort and Convenience">Height Adjustable Drivers Seat</Option>
  <Option OptionGroup="Comfort and Convenience">Pollen Filter</Option>
  <Option OptionGroup="Comfort and Convenience">Privacy Glass</Option>
  <Option OptionGroup="Comfort and Convenience">Remote Boot Release</Option>
  <Option OptionGroup="Comfort and Convenience">Split Rear Seats</Option>
  <Option>Something else</Option>
  <Option>Yet another thing</Option>
  <Option OptionGroup="Paint or Trim and Upholstery">Metallic Paint</Option>
  <Option OptionGroup="Exterior Equipment">Power Assisted Steering (PAS)</Option>
  <Option OptionGroup="Interior Equipment">Leather Steering Wheel</Option>
  <Option OptionGroup="In Car Entertainment">CD Radio</Option>
  <Option OptionGroup="Security">Central Locking</Option>
</Options>

<table>
   <tr>
      <th>Safety</th>
      <td>Driver Airbag</td>
   </tr>
   <tr>
      <th>Comfort and Convenience</th>
      <td>Front Electric Windows, Height Adjustable Drivers Seat, Pollen Filter, Privacy Glass, Remote Boot Release, Split Rear Seats</td>
   </tr>
   <tr>
      <th>Paint or Trim and Upholstery</th>
      <td>Metallic Paint</td>
   </tr>
   <tr>
      <th>Exterior Equipment</th>
      <td>Power Assisted Steering (PAS)</td>
   </tr>
   <tr>
      <th>Interior Equipment</th>
      <td>Leather Steering Wheel</td>
   </tr>
   <tr>
      <th>In Car Entertainment</th>
      <td>CD Radio</td>
   </tr>
   <tr>
      <th>Security</th>
      <td>Central Locking</td>
   </tr>
   <tr>
      <th>Other</th>
      <td>Something else, Yet another thing</td>
   </tr>
</table>

答案 1 :(得分:1)

这应该有效:

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

  <xsl:template match="/">
    <table>
      <xsl:for-each select="Options/Option/@OptionGroup[not(. = preceding::Option/@OptionGroup)]">
        <xsl:call-template name="OutputGroup">
          <xsl:with-param name="title" select="." />
          <xsl:with-param name="items" select="../../Option[@OptionGroup = current()]" />
        </xsl:call-template>
      </xsl:for-each>

      <xsl:if test="Options/Option[not(@OptionGroup)]">
        <xsl:call-template name="OutputGroup">
          <xsl:with-param name="title" select="'Other'" />
          <xsl:with-param name="items" select="Options/Option[not(@OptionGroup)]" />
        </xsl:call-template>
      </xsl:if>
    </table>
  </xsl:template>
  <xsl:template name="OutputGroup">
    <xsl:param name="title" />
    <xsl:param name="items" />

    <tr>
      <th>
        <xsl:value-of select="$title"/>
      </th>
    </tr>
    <tr>
      <td>
        <xsl:apply-templates select="$items" />
      </td>
    </tr>

  </xsl:template>

  <xsl:template match="Option">
    <xsl:if test="position() > 1">
      <xsl:text>, </xsl:text>
    </xsl:if>
    <xsl:value-of select="."/>
  </xsl:template>