使用XSL的XML子元素的不同值列表

时间:2012-10-26 15:35:21

标签: xml xslt distinct-values

我的XML如下所示

<?xml version="1.0" encoding="UTF-8"?>
<Set>
<Bundles>
    <BundleID>1</BundleID>
    <BundleDetails>
        <Classification>A</Classification>
        <TrackingID>34675</TrackingID>
    </BundleDetails>
    <BundleQty>12</BundleQty>
</Bundles>
<Bundles>
    <BundleID>2</BundleID>
    <BundleDetails>
        <Classification>B</Classification>
        <TrackingID>4563</TrackingID>
    </BundleDetails>
    <BundleDetails>
        <Classification>A</Classification>
        <TrackingID>4563</TrackingID>
    </BundleDetails>
    <BundleQty>34</BundleQty>
</Bundles>
<Bundles>
    <BundleID>3</BundleID>
    <BundleDetails>
        <Classification>A</Classification>
        <TrackingID>2343243</TrackingID>
    </BundleDetails>
    <BundleQty>22</BundleQty>
</Bundles>
<Bundles>
    <BundleID>4</BundleID>
    <BundleDetails>
        <Classification>A</Classification>
        <TrackingID>123231</TrackingID>
    </BundleDetails>
    <BundleDetails>
        <Classification>B</Classification>
    </BundleDetails>
    <BundleDetails>
        <Classification>B</Classification>
        <TrackingID>42342</TrackingID>
    </BundleDetails>
    <BundleQty>33</BundleQty>
</Bundles>
<Bundles>
    <BundleID>5</BundleID>
    <BundleDetails>
        <Classification>A</Classification>
        <TrackingID>123231</TrackingID>
    </BundleDetails>
    <BundleDetails>
        <Classification>A</Classification>
        <TrackingID>42342</TrackingID>
    </BundleDetails>
    <BundleDetails>
        <Classification>B</Classification>
        <TrackingID>124512</TrackingID>
    </BundleDetails>
    <BundleQty>21</BundleQty>
</Bundles>
</Set>

我需要获取每个Set / Bundles的详细信息,如下所示

Bundle# Qty  Classes
1      12      A
2      34      A,B
3      22      A
4      33     A,B
5      21     A,B

我从下面开始,但是获得了不同的类列表。需要一些指导,

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

<xsl:template match="/">
  <html>
  <body>
  <p>Set Details</p>
  <table>
       <xsl:for-each select="Set/Bundles">
        <tr>
          <td><xsl:value-of select="BundleID"/></td>
          <td><xsl:value-of select="BundleQty"/></td>
          <td>--Distinct List of ./BundleDetails/Classification </td>
        </tr>
      </xsl:for-each>
   </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

提前感谢您的帮助!

谢谢!

1 个答案:

答案 0 :(得分:2)

此转化

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kClassByValAndGrParent" match="Classification"
  use="concat(generate-id(../..),'+', .)"/>

 <xsl:template match="*"><xsl:apply-templates/></xsl:template>

 <xsl:template match="/*">
   <table border="1">
    <tr>
      <th>Bundle#</th><th>Qty</th><th>Classes</th>
    </tr>
    <xsl:apply-templates/>
   </table>
 </xsl:template>

 <xsl:template match="Bundles">
  <tr>
    <xsl:apply-templates select="*[not(self::BundleDetails)]"/>
   <td>
    <xsl:apply-templates select=
      "BundleDetails/Classification
                      [generate-id()
                      =
                       generate-id(key('kClassByValAndGrParent',
                                        concat(generate-id(../..),'+', .)
                                      )[1]
                                  )
                      ]
      "/>
   </td>
  </tr>
 </xsl:template>

 <xsl:template match="BundleID|BundleQty">
  <td><xsl:value-of select="."/></td>
 </xsl:template>

 <xsl:template match="BundleDetails"/>

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

应用于提供的XML文档

<Set>
    <Bundles>
        <BundleID>1</BundleID>
        <BundleDetails>
            <Classification>A</Classification>
            <TrackingID>34675</TrackingID>
        </BundleDetails>
        <BundleQty>12</BundleQty>
    </Bundles>
    <Bundles>
        <BundleID>2</BundleID>
        <BundleDetails>
            <Classification>B</Classification>
            <TrackingID>4563</TrackingID>
        </BundleDetails>
        <BundleDetails>
            <Classification>A</Classification>
            <TrackingID>4563</TrackingID>
        </BundleDetails>
        <BundleQty>34</BundleQty>
    </Bundles>
    <Bundles>
        <BundleID>3</BundleID>
        <BundleDetails>
            <Classification>A</Classification>
            <TrackingID>2343243</TrackingID>
        </BundleDetails>
        <BundleQty>22</BundleQty>
    </Bundles>
    <Bundles>
        <BundleID>4</BundleID>
        <BundleDetails>
            <Classification>A</Classification>
            <TrackingID>123231</TrackingID>
        </BundleDetails>
        <BundleDetails>
            <Classification>B</Classification>
        </BundleDetails>
        <BundleDetails>
            <Classification>B</Classification>
            <TrackingID>42342</TrackingID>
        </BundleDetails>
        <BundleQty>33</BundleQty>
    </Bundles>
    <Bundles>
        <BundleID>5</BundleID>
        <BundleDetails>
            <Classification>A</Classification>
            <TrackingID>123231</TrackingID>
        </BundleDetails>
        <BundleDetails>
            <Classification>A</Classification>
            <TrackingID>42342</TrackingID>
        </BundleDetails>
        <BundleDetails>
            <Classification>B</Classification>
            <TrackingID>124512</TrackingID>
        </BundleDetails>
        <BundleQty>21</BundleQty>
    </Bundles>
</Set>

生成想要的正确结果

<table border="1">
   <tr>
      <th>Bundle#</th>
      <th>Qty</th>
      <th>Classes</th>
   </tr>
   <tr>
      <td>1</td>
      <td>12</td>
      <td>A</td>
   </tr>
   <tr>
      <td>2</td>
      <td>34</td>
      <td>B,A</td>
   </tr>
   <tr>
      <td>3</td>
      <td>22</td>
      <td>A</td>
   </tr>
   <tr>
      <td>4</td>
      <td>33</td>
      <td>A,B</td>
   </tr>
   <tr>
      <td>5</td>
      <td>21</td>
      <td>A,B</td>
   </tr>
</table>

<强>解释

  1. 正确使用 Muenchian Grouping Method

  2. 正确的复合 key 定义,指定任何Classification作为其祖父项及其字符串值的函数。