【问题标题】:Distinct List of Values from XML child elements using XSL使用 XSL 的 XML 子元素的不同值列表
【发布时间】:2012-10-16 21:36:02
【问题描述】:

我有如下的 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>

提前感谢您的帮助!

谢谢!

【问题讨论】:

    标签: xml xslt distinct-values


    【解决方案1】:

    这种转变

    <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 作为其祖父及其字符串值的函数。

    【讨论】:

    • +1 我唯一要添加的是xsl:sortxsl:apply-templatesClassification
    • @DevNull,谢谢,你是对的。由于Bundles 已经按BundleID 排序,我没有费心添加任何排序。我们甚至可以假设可能有多个Bundles 具有相同的BundleID,然后我们应该添加另一个级别的分组,但这离真正的XML 文档太远了。
    猜你喜欢
    • 2018-01-15
    • 1970-01-01
    • 2011-09-30
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多