XSLT 1.0 Группировка по дате бронирования

У меня есть следующие данные XML:

<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="serverReserve_1.xsl" ?>
  <!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->


  <reservation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="localSchema.xsd">
    <new>
      <name>Ah Huat</name>
      <icNum>930330033330</icNum>
      <contact>0182345679</contact>
      <reserveDate>20150402</reserveDate>
      <reserveTime>08:00am</reserveTime>
      <day>4</day>
      <totalPeople>2</totalPeople>
      <room unit="2" type="King Suite">
        <bedType>King Bed</bedType>
        <extraRequirement>One more quilt</extraRequirement>
        <extraRequirement>One more bed</extraRequirement>
      </room>
    </new>

    <new>
      <name>Ah Huat</name>
      <icNum>930330033330</icNum>
      <contact>0182345679</contact>
      <reserveDate>20150402</reserveDate>
      <reserveTime>08:00am</reserveTime>
      <day>4</day>
      <totalPeople>2</totalPeople>
      <room unit="2" type="King Suite">
        <bedType>King Bed</bedType>
        <extraRequirement>One more quilt</extraRequirement>
        <extraRequirement>One more bed</extraRequirement>
      </room>
    </new>

    <new>
      <name>Ah Huat</name>
      <icNum>930330033330</icNum>
      <contact>0182345679</contact>
      <reserveDate>20150414</reserveDate>
      <reserveTime>08:00am</reserveTime>
      <day>4</day>
      <totalPeople>2</totalPeople>
      <room unit="2" type="King Suite">
        <bedType>King Bed</bedType>
        <extraRequirement>One more quilt</extraRequirement>
        <extraRequirement>One more bed</extraRequirement>
      </room>
    </new>

    <delete>
      <name>Hoo Chee Sem</name>
      <icNum>930110011101</icNum>
      <reserveDate>20150411</reserveDate>
      <reserveTime>08:00am</reserveTime>
      <room unit="2" type="Hillview Deluxe">
        <bedType>2 Single Bed</bedType>
      </room>
    </delete>

    <roomList>
      <rooms code="R1">Single Room</rooms>
      <rooms code="R2">Double Room</rooms>
      <rooms code="R3">Twin Room</rooms>
      <rooms code="R4">Duplex Room</rooms>
      <rooms code="R5">King Suite</rooms>
      <rooms code="R6">Hillview Deluxe</rooms>
      <rooms code="R7">Seaview Deluxe</rooms>
    </roomList>

    <bedList>
      <beds code="B1">Single Bed</beds>
      <beds code="B2">2 Single Beds</beds>
      <beds code="B3">King Bed</beds>
      <beds code="B4">2 King Beds</beds>
      <beds code="B5">Queen Bed</beds>
      <beds code="B6">2 Queen Beds</beds>
      <beds code="B7">3 Queen Beds</beds>
    </bedList>
  </reservation>

В XSLT 1.0 я хочу сгруппировать по резервной дате и вычислить количество резервных дат. Таким образом, в приведенных выше данных мне понадобится таблица, которая показывает дату резерва и общую сумму бронирования, сделанного на эту дату.

Как я могу сделать это в XSLT 1.0? Когда я пытаюсь использовать этот метод, я получаю сообщение об ошибке: «Ошибка анализа таблицы стилей XSLT».

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

  <xsl:template match="/">
    <html>

    <head>
      <title>reserve.xsl</title>
    </head>

    <body>
      <xsl:key name="groups" match="/reservation/new" use="reserveDate" />

      <xsl:template match="/reservation">
        <xsl:apply-templates select="new[generate-id() = generate-id(key('groups', reserveDate)[1])]" />
      </xsl:template>
      <xsl:template match="new">
        <h1>
                        <xsl:value-of select="reserveDate"/>
                    </h1>
        <table id="{reserveDate}">
          <tr class="heading">
            <th scope="col">Member Id</th>
            <th scope="col">First Name</th>
            <th scope="col">Last Name</th>
          </tr>
          <xsl:for-each select="key('groups', reserveDate)">
            <tr>
              <td>
                <xsl:value-of select="name" />
              </td>
              <td>
                <xsl:value-of select="reserveTime" />
              </td>
              <td>
                <xsl:value-of select="contact" />
              </td>
            </tr>
          </xsl:for-each>
        </table>
      </xsl:template>
    </body>

    </html>
  </xsl:template>

</xsl:stylesheet>


person Etto Sama    schedule 22.03.2015    source источник
comment
Это ваша полная таблица стилей? Где находится корневой элемент xsl:stylesheet?   -  person michael.hor257k    schedule 22.03.2015
comment
Мои корневые элементы xsl:stylesheet: ‹?xml version=1.0 encoding=UTF-8?› ‹xsl:stylesheet xmlns:xsl=w3.org/1999/XSL/Transform version=1.0› ‹xsl:output method=html/› ‹xsl:output method=html indent=yes/› ‹xsl:template match= /›   -  person Etto Sama    schedule 22.03.2015
comment
Пожалуйста, не размещайте код в комментариях - вместо этого отредактируйте свой вопрос и включите полную таблицу стилей, а не блоки для сборки. FWIW, ваш исходный код работает для меня, если я вставлю его в элемент xsl:stylesheet.   -  person michael.hor257k    schedule 22.03.2015
comment
Сообщение отредактировано. Я все еще не мог заставить свою работать   -  person Etto Sama    schedule 22.03.2015
comment
Ну, это совершенно другая таблица стилей, чем предыдущая. Примечание. 1. xsl:key не может находиться внутри шаблона; 2. шаблон не может находиться внутри другого шаблона.   -  person michael.hor257k    schedule 22.03.2015
comment
Ой! Итак, как я собираюсь изменить это? Я все еще новичок и учусь, поэтому я не слишком уверен, как это исправить.   -  person Etto Sama    schedule 22.03.2015


Ответы (1)


Вы можете изменить свой XSLT следующим образом: переместите шаблон, соответствующий reservation, за пределы шаблона, соответствующего корневому уровню:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">    
<xsl:output method="html" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
  <xsl:key name="groups" match="/reservation/new" use="reserveDate" />
  <xsl:template match="/">
    <hmtl>
      <head>
        <title>reserve.xsl</title>
      </head>
      <body>
        <xsl:apply-templates/>
      </body>
    </hmtl>
    </xsl:template>
    <xsl:template match="/reservation">
    ....
    </xsl:template>
</xsl:stylesheet>

В шаблоне, соответствующем корневому каталогу, apply templates вызовет шаблон, соответствующий reservation:

<body>
  <xsl:apply-templates/>
</body>

Демо

person matthias_h    schedule 22.03.2015