Как сортировать с разными значениями? - PullRequest
0 голосов
/ 12 февраля 2012

Теперь приведенная ниже сортировка xsl основана на различном типе доски + меньшая цена. Типы номеров,

Я хочу отсортировать отдельные типы досок + меньшие цены на типы комнат с различными "RoomCount, AdultCount и ChildCount"

ниже 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>

Выход из игры

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 Ответ

1 голос
/ 12 февраля 2012

Ниже приведено решение, которое значительно отличается от того, как вы работали.
Во-первых, я предлагаю не использовать функцию набора узлов, поскольку она имеет пространство имен, зависящее от процессора xslt, и оно вам все равно не нужно.1002 * Во-вторых, мне неясно, какая группировка вам нужна.Из требуемого результата я пришел к выводу, что это была доска + разделение между туалетом и ванной комнатой.Это может быть достигнуто путем группировки на доске + подстрока типа комнаты после первого пробела.
См. Ниже.---> примечание: см. ниже комментарий: одна скобка переместилась вправо, вместо
... '|', Board))) [1]] теперь это
... '|',Board)) [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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...