如何使用不同的值进行排序?

时间:2012-02-11 20:03:22

标签: xslt

现在下面的xsl排序基于不同的Board Type +更低的房间类型,

我想用不同的“BoardCount,AdultCount和ChildCount”来分类不同的Board Type +更低价格的房间类型

基于此结果

下面的xml
**total 2 rooms
1st room, 1 adult , 0 child
2nd room, 2 adults , 0 child**

在这个原因中,xml是这样的:

<HotelInfo xmlns="http://www.Test.com/schemas/2005/06/messages"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.Test.com/schemas/2005/06/messages test.xsd" >
<Service>
<HotelCode>1001</HotelCode>

<AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>1</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>ROOM ONLY</Board>
  <RoomType>SINGLE WITH NO TOILET</RoomType>
 <Price>
  <Amount>19.840</Amount>
  </Price>

  </AvailableRoom>
 <AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>1</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>BED AND BREAKFAST</Board>
  <RoomType>SINGLE WITH NO TOILET</RoomType>
 <Price>
  <Amount>19.840</Amount>
  </Price>

  </AvailableRoom>
 <AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>1</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>ROOM ONLY</Board>
  <RoomType>SINGLE WITH BATHROOM</RoomType>
 <Price>
  <Amount>25.790</Amount>
  </Price>

  </AvailableRoom>
 <AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>1</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>BED AND BREAKFAST</Board>
  <RoomType>SINGLE WITH BATHROOM</RoomType>
 <Price>
  <Amount>25.790</Amount>
  </Price>

  </AvailableRoom>
 <AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>1</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>HALF BOARD</Board>
  <RoomType>SINGLE WITH NO TOILET</RoomType>
 <Price>
  <Amount>25.790</Amount>
  </Price>

  </AvailableRoom>
 <AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>1</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>HALF BOARD</Board>
  <RoomType>SINGLE WITH BATHROOM</RoomType>
 <Price>
  <Amount>31.740</Amount>
  </Price>

  </AvailableRoom>
 <AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>1</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>FULL BOARD</Board>
  <RoomType>SINGLE WITH NO TOILET</RoomType>
 <Price>
  <Amount>31.740</Amount>
  </Price>

  </AvailableRoom>
 <AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>2</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>ROOM ONLY</Board>
  <RoomType>DOUBLE WITH NO TOILET</RoomType>
 <Price>
  <Amount>33.730</Amount>
  </Price>

  </AvailableRoom>
 <AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>2</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>BED AND BREAKFAST</Board>
  <RoomType>DOUBLE WITH NO TOILET</RoomType>
 <Price>
  <Amount>33.730</Amount>
  </Price>

  </AvailableRoom>
 <AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>1</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>FULL BOARD</Board>
  <RoomType>SINGLE WITH BATHROOM</RoomType>
 <Price>
  <Amount>37.690</Amount>
  </Price>

  </AvailableRoom>
 <AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>2</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>ROOM ONLY</Board>
  <RoomType>DOUBLE WITH BATHROOM</RoomType>
 <Price>
  <Amount>41.670</Amount>
  </Price>

  </AvailableRoom>
 <AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>2</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>BED AND BREAKFAST</Board>
  <RoomType>DOUBLE WITH BATHROOM</RoomType>
 <Price>
  <Amount>41.670</Amount>
  </Price>

  </AvailableRoom>
 <AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>2</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>HALF BOARD</Board>
  <RoomType>DOUBLE WITH NO TOILET</RoomType>
 <Price>
  <Amount>45.630</Amount>
  </Price>

  </AvailableRoom>
 <AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>2</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>HALF BOARD</Board>
  <RoomType>DOUBLE WITH BATHROOM</RoomType>
 <Price>
  <Amount>53.570</Amount>
  </Price>

  </AvailableRoom>
 <AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>2</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>FULL BOARD</Board>
  <RoomType>DOUBLE WITH NO TOILET</RoomType>
 <Price>
  <Amount>57.530</Amount>
  </Price>

  </AvailableRoom>
 <AvailableRoom>
 <HotelOccupancy>
  <RoomCount>1</RoomCount>
 <Occupancy>
  <AdultCount>2</AdultCount>
  <ChildCount>0</ChildCount>
  </Occupancy>
  </HotelOccupancy>

  <Board>FULL BOARD</Board>
  <RoomType>DOUBLE WITH BATHROOM</RoomType>
 <Price>
  <Amount>65.470</Amount>
  </Price>

  </AvailableRoom>


  </Service>

  <Service>
    <HotelCode>1002</HotelCode>
'
'
'
'
'
  </Service>

</HotelInfo>

这是XSL

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:mg="http://www.Test.com/schemas/2005/06/messages"
  xmlns:ms="urn:schemas-microsoft-com:xslt"
  exclude-result-prefixes="ms mg">

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

  <xsl:key name="by-board" match="mg:AvailableRoom" use="concat(generate-id(parent::mg:Service), '|', mg:Board)"/>
  <xsl:key name="by-rt" match="mg:AvailableRoom" use="concat(generate-id(parent::mg:Service), '|', mg:Board, '|', mg:RoomType)"/>

  <xsl:template match="/">
    <html lang="en">
      <head>
        <title>Rooms</title>
      </head>
      <body>
        <h1>Rooms</h1>
        <xsl:apply-templates select="mg:HotelInfo/mg:Service"/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="mg:HotelInfo/mg:Service">

    <div>
Total 2 rooms<br></br>
1st room, 1 adult , 0 child<br></br>
2nd room, 2 adults , 0 child<br></br>
      <h2>Service Node <xsl:value-of select="position()"/></h2>
      <table border="1">
        <thead>
          <th>Room type, Board</th>
          <th>RoomCount, AdultCount, ChildCount</th>
          <th>Price</th>
        </thead>

        <xsl:apply-templates select="mg:AvailableRoom[generate-id() = generate-id(key('by-board', concat(generate-id(parent::mg:Service), '|', mg:Board))[1]) and count(key('by-board', concat(generate-id(parent::mg:Service), '|', mg:Board))) &gt;= 2]" mode="group"/>
      </table>
    </div>

  </xsl:template>

  <xsl:template match="mg:AvailableRoom" mode="group">
    <tbody>
      <xsl:variable name="grouprtf">
        <xsl:for-each select="key('by-board', concat(generate-id(parent::mg:Service), '|', mg:Board))[generate-id() = generate-id(key('by-rt', concat(generate-id(parent::mg:Service), '|', mg:Board, '|', mg:RoomType))[1])]">
          <xsl:for-each select="key('by-rt', concat(generate-id(parent::mg:Service), '|', mg:Board, '|', mg:RoomType))">
            <xsl:sort select="mg:Price/mg:Amount" data-type="number"/>
            <xsl:if test="position() = 1">
              <xsl:copy-of select="."/>
            </xsl:if>
          </xsl:for-each>
        </xsl:for-each>
      </xsl:variable>
      <xsl:variable name="sortedgrouprtf">
        <xsl:for-each select="ms:node-set($grouprtf)/mg:AvailableRoom">
          <xsl:sort select="mg:Price/mg:Amount" data-type="number"/>
          <xsl:if test="position() &lt;= 2">
            <xsl:copy-of select="."/>
          </xsl:if>
        </xsl:for-each>
      </xsl:variable>
      <xsl:variable name="groupset" select="ms:node-set($sortedgrouprtf)/mg:AvailableRoom"/>
      <xsl:apply-templates select="$groupset"/>
      <tr>
        <td>&#160;</td>
        <td>&#160;</td>
        <th>Total Price: <xsl:value-of select="format-number(sum($groupset/mg:Price/mg:Amount), '#.000')"/>
      </th>
      </tr>
    </tbody>
  </xsl:template>

  <xsl:template match="mg:AvailableRoom">
    <tr>
      <td>
        <xsl:value-of select="concat(mg:RoomType, ', ', mg:Board)"/>
      </td>
      <td>
        <xsl:value-of select="concat(mg:HotelOccupancy/mg:RoomCount, ', ',mg:HotelOccupancy/mg:Occupancy/mg:AdultCount, ', ', mg:HotelOccupancy/mg:Occupancy/mg:ChildCount)"/>
      </td>
      <td align="right">
        <xsl:value-of select="format-number(mg:Price/mg:Amount, '#.000')"/>
      </td>
    </tr>

  </xsl:template>
</xsl:stylesheet>

Out Put Is

Rooms
Total 2 rooms
1st room, 1 adult , 0 child
2nd room, 2 adults , 0 child
Service Node 1
Room type, Board    RoomCount, AdultCount, ChildCount   Price
SINGLE WITH NO TOILET, ROOM ONLY    1, 1, 0     19.840
SINGLE WITH BATHROOM, ROOM ONLY     1, 1, 0     25.790
        Total Price: 45.630
SINGLE WITH NO TOILET, BED AND BREAKFAST    1, 1, 0     19.840
SINGLE WITH BATHROOM, BED AND BREAKFAST     1, 1, 0     25.790
        Total Price: 45.630
SINGLE WITH NO TOILET, HALF BOARD   1, 1, 0     25.790
SINGLE WITH BATHROOM, HALF BOARD    1, 1, 0     31.740
        Total Price: 57.530
SINGLE WITH NO TOILET, FULL BOARD   1, 1, 0     31.740
SINGLE WITH BATHROOM, FULL BOARD    1, 1, 0     37.690
        Total Price: 69.430

我需要像这样

Rooms
Total 2 rooms
1st room, 1 adult , 0 child
2nd room, 2 adults , 0 child
Service Node 1
Room type, Board    RoomCount, AdultCount, ChildCount   Price
SINGLE WITH NO TOILET, ROOM ONLY    1, 1, 0     19.840
DOUBLE WITH NO TOILET, ROOM ONLY    1, 2, 0     33.730
        Total Price: 53.570
SINGLE WITH NO TOILET, BED AND BREAKFAST    1, 1, 0     19.840
DOUBLE WITH NO TOILET, BED AND BREAKFAST    1, 2, 0     33.730
        Total Price: 53.570
SINGLE WITH NO TOILET, HALF BOARD   1, 1, 0     25.790
DOUBLE WITH NO TOILET, HALF BOARD   1, 2, 0     45.630
        Total Price: 71.420
SINGLE WITH NO TOILET, FULL BOARD   1, 1, 0     31.740
DOUBLE WITH NO TOILET, FULL BOARD   1, 2, 0     57.530
        Total Price: 89.270

希望得到你宝贵的帮助

1 个答案:

答案 0 :(得分:1)

以下是与您的工作方式有很大不同的解决方案 首先,我建议不要使用节点集函数,因为它有一个xslt处理器相关的命名空间,无论如何你都不需要它。
其次,我不清楚你需要什么分组。从所要求的结果,我推断出这是董事会+没有厕所和浴室之间的区别。这可以通过在第一个空白后分组onboard + roomtype的子字符串来实现 见下文。 ---&GT;注意:见下面的评论:一个支架向右移动,而不是
......'|',董事会)))[1]]现在是 ......'|',董事会))[1])]
这确保了MSXML3 / 4/6不会抛出错误。

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

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

  <xsl:key name="boardAndType" match="AvailableRoom" use="concat(substring-after(RoomType, ' '), '|', Board)"/>

    <xsl:template match="/">
        <html lang="en">
            <head>
                <title>Rooms</title>
            </head>
            <body>
                <h1>Rooms</h1>
                <xsl:apply-templates select="//Service"/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="Service">
        <div>
            <h2>Service Node <xsl:value-of select="position()"/></h2>
            <table border="1">
                <thead>
                    <th>Room type, Board</th>
                    <th>RoomCount, AdultCount, ChildCount</th>
                    <th>Price</th>
                </thead>
            <xsl:apply-templates select="//AvailableRoom[generate-id() = generate-id(key('boardAndType', concat(substring-after(RoomType, ' '), '|', Board))[1])]" mode="group"/>
            </table>
        </div>
    </xsl:template>

    <xsl:template match="AvailableRoom" mode="group">
        <xsl:variable name="groupset" select="key('boardAndType', concat(substring-after(RoomType, ' '), '|', Board))"/>
        <tbody>
            <xsl:for-each select="$groupset">
                <tr>
                    <td><xsl:value-of select="concat(RoomType, ', ',Board)"/></td>
                    <td><xsl:value-of select="concat(HotelOccupancy/RoomCount, ', ',HotelOccupancy/Occupancy/AdultCount, ', ', HotelOccupancy/Occupancy/ChildCount)"/></td>
                    <td align="right"><xsl:value-of select="format-number(Price/Amount, '#.000')"/></td>
                </tr>
            </xsl:for-each>
            <tr>
                <td>&#160;</td>
                <td>&#160;</td>
                <td>Total Price: <xsl:value-of select="format-number(sum($groupset/Price/Amount), '#.000')"/></td>
            </tr>
        </tbody>
    </xsl:template>
</xsl:stylesheet>

这导致

<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Rooms</title>
    </head>
    <body>
        <h1>Rooms</h1>
        <div>
            <h2>Service Node 1</h2>
            <table border="1">
                <thead>
                    <th>Room type, Board</th>
                    <th>RoomCount, AdultCount, ChildCount</th>
                    <th>Price</th>
                </thead>
                <tbody>
                    <tr>
                        <td>SINGLE WITH NO TOILET, ROOM ONLY</td>
                        <td>1, 1, 0</td>
                        <td align="right">19.840</td>
                    </tr>
                    <tr>
                        <td>DOUBLE WITH NO TOILET, ROOM ONLY</td>
                        <td>1, 2, 0</td>
                        <td align="right">33.730</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>Total Price: 53.570</td>
                    </tr>
                </tbody>
                <tbody>
                    <tr>
                        <td>SINGLE WITH NO TOILET, BED AND BREAKFAST</td>
                        <td>1, 1, 0</td>
                        <td align="right">19.840</td>
                    </tr>
                    <tr>
                        <td>DOUBLE WITH NO TOILET, BED AND BREAKFAST</td>
                        <td>1, 2, 0</td>
                        <td align="right">33.730</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>Total Price: 53.570</td>
                    </tr>
                </tbody>
                <tbody>
                    <tr>
                        <td>SINGLE WITH BATHROOM, ROOM ONLY</td>
                        <td>1, 1, 0</td>
                        <td align="right">25.790</td>
                    </tr>
                    <tr>
                        <td>DOUBLE WITH BATHROOM, ROOM ONLY</td>
                        <td>1, 2, 0</td>
                        <td align="right">41.670</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>Total Price: 67.460</td>
                    </tr>
                </tbody>
                <tbody>
                    <tr>
                        <td>SINGLE WITH BATHROOM, BED AND BREAKFAST</td>
                        <td>1, 1, 0</td>
                        <td align="right">25.790</td>
                    </tr>
                    <tr>
                        <td>DOUBLE WITH BATHROOM, BED AND BREAKFAST</td>
                        <td>1, 2, 0</td>
                        <td align="right">41.670</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>Total Price: 67.460</td>
                    </tr>
                </tbody>
                <tbody>
                    <tr>
                        <td>SINGLE WITH NO TOILET, HALF BOARD</td>
                        <td>1, 1, 0</td>
                        <td align="right">25.790</td>
                    </tr>
                    <tr>
                        <td>DOUBLE WITH NO TOILET, HALF BOARD</td>
                        <td>1, 2, 0</td>
                        <td align="right">45.630</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>Total Price: 71.420</td>
                    </tr>
                </tbody>
                <tbody>
                    <tr>
                        <td>SINGLE WITH BATHROOM, HALF BOARD</td>
                        <td>1, 1, 0</td>
                        <td align="right">31.740</td>
                    </tr>
                    <tr>
                        <td>DOUBLE WITH BATHROOM, HALF BOARD</td>
                        <td>1, 2, 0</td>
                        <td align="right">53.570</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>Total Price: 85.310</td>
                    </tr>
                </tbody>
                <tbody>
                    <tr>
                        <td>SINGLE WITH NO TOILET, FULL BOARD</td>
                        <td>1, 1, 0</td>
                        <td align="right">31.740</td>
                    </tr>
                    <tr>
                        <td>DOUBLE WITH NO TOILET, FULL BOARD</td>
                        <td>1, 2, 0</td>
                        <td align="right">57.530</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>Total Price: 89.270</td>
                    </tr>
                </tbody>
                <tbody>
                    <tr>
                        <td>SINGLE WITH BATHROOM, FULL BOARD</td>
                        <td>1, 1, 0</td>
                        <td align="right">37.690</td>
                    </tr>
                    <tr>
                        <td>DOUBLE WITH BATHROOM, FULL BOARD</td>
                        <td>1, 2, 0</td>
                        <td align="right">65.470</td>
                    </tr>
                    <tr>
                        <td>&nbsp;</td>
                        <td>&nbsp;</td>
                        <td>Total Price: 103.160</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </body>
</html>