简体   繁体   English

XSLT 1.0按标签分组

[英]XSLT 1.0 Group By Tags

I have the following XML data: 我有以下XML数据:

  <result>
<row>
<CountryId>26</CountryId>
<CountryName>United Kingdom</CountryName>
<NoOfNights>1</NoOfNights>
<AccommodationID>6004</AccommodationID>
<RoomID>1</RoomID>
<RoomName>Double for Sole Use</RoomName>
<RatePlanID>1</RatePlanID>
<RoomRatePlan>Advance</RoomRatePlan>
<NoOfSameTypeRoom>0</NoOfSameTypeRoom>
<RoomSize/>
<Max_Person>1</Max_Person>
<RackRate>189</RackRate>
<CurrencySymbol>&pound;</CurrencySymbol>
<NoOfRoomsAvailable>4</NoOfRoomsAvailable>
<Rate>79.00</Rate>
<RatePerDay>27 Mar 2013_79.00</RatePerDay>
</row>
<row>
<CountryId>26</CountryId>
<CountryName>United Kingdom</CountryName>
<NoOfNights>1</NoOfNights>
<AccommodationID>6004</AccommodationID>
<RoomID>1</RoomID>
<RoomName>Double for Sole Use</RoomName>
<RatePlanID>2</RatePlanID>
<RoomRatePlan>Standard</RoomRatePlan>
<NoOfSameTypeRoom>0</NoOfSameTypeRoom>
<RoomSize/>
<Max_Person>1</Max_Person>
<RackRate>189</RackRate>
<CurrencySymbol>&pound;</CurrencySymbol>
<NoOfRoomsAvailable>5</NoOfRoomsAvailable>
<Rate>89.00</Rate>
<RatePerDay>27 Mar 2013_89.00</RatePerDay>
</row>
<row>
<CountryId>26</CountryId>
<CountryName>United Kingdom</CountryName>
<NoOfNights>1</NoOfNights>
<AccommodationID>6004</AccommodationID>
<RoomID>2</RoomID>
<RoomName>Double Room</RoomName>
<RatePlanID>1</RatePlanID>
<RoomRatePlan>Advance</RoomRatePlan>
<NoOfSameTypeRoom>0</NoOfSameTypeRoom>
<RoomSize/>
<Max_Person>2</Max_Person>
<RackRate>199</RackRate>
<CurrencySymbol>&pound;</CurrencySymbol>
<NoOfRoomsAvailable>5</NoOfRoomsAvailable>
<Rate>89.00</Rate>
<RatePerDay>27 Mar 2013_89.00</RatePerDay>
</row>
 </result>

My XSLT for the above xml is this: 我上面的xml的XSLT是这样的:

<?xml version="1.0" encoding="utf-8" ?>

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

  <xsl:output omit-xml-declaration="yes" indent="yes" method="xml" />
  <xsl:strip-space elements="*"/>

  <!-- Default template : ignore unrecognized elements and text -->
  <xsl:template match="*|text()" />

  <!-- Match document root : add hotels element and process each children node of result -->
  <xsl:template match="/">
    <hotels>
      <!-- We assume that the XML documents are always going to follow the structure:
             result as the root node and xml_acc elements as its children -->
      <xsl:for-each select="result/row">
        <result>
          <hotel_rooms>
            <xsl:element name="hotel_id">
              <xsl:value-of select="AccommodationID"/>
            </xsl:element>
            <xsl:apply-templates />
          </hotel_rooms>
          <xsl:element name="Rate">
            <xsl:element name="RoomRatePlan">
              <xsl:value-of select="RoomRatePlan"/>
            </xsl:element>
            <xsl:element name="numeric_price">
              <xsl:value-of select="Rate"/>
            </xsl:element>
          </xsl:element>
        </result>
      </xsl:for-each>
    </hotels>
  </xsl:template>

  <!-- Elements to be copied as they are -->

  <xsl:template match="NoOfNights|RoomName|RoomSize|Max_Person|RackRate|RatePerDay|CurrencySymbol|NoOfRoomsAvailable|RoomDescription|RoomFacilities|PolicyComments|Breakfast|Policy|Message">
    <xsl:copy-of select="." />
  </xsl:template>

  <xsl:template match="Photo_Max60">
    <RoomImages>
      <Photo_Max60>
        <xsl:value-of select="." />
      </Photo_Max60>
      <Photo_Max300>
        <xsl:value-of select="../Photo_Max300" />
      </Photo_Max300>
      <Photo_Max500>
        <xsl:value-of select="../Photo_Max500" />
      </Photo_Max500>
    </RoomImages>
  </xsl:template>
</xsl:stylesheet>

In XSLT 1.0, I want to group by Room ID and Hotel ID . 在XSLT 1.0中,我想按房间ID和酒店ID进行分组。 so in the above data, I Want the result like this. 所以在上面的数据中,我想要这样的结果。

<hotels>
     <result>
      <hotel_rooms>
        <hotel_id>6004</hotel_id>
        <NoOfNights>1</NoOfNights>
        <RoomID>1</RoomID>
        <RoomName>Double for Sole Use</RoomName>
        <RoomSize/>
        <Max_Person>1</Max_Person>
        <RackRate>189</RackRate>
        <CurrencySymbol>&pound;</CurrencySymbol>
        <NoOfRoomsAvailable>4</NoOfRoomsAvailable>
        <RatePerDay>27 Mar 2013_79.00</RatePerDay>
     </hotel_rooms>
     <Rate>
     <RoomRatePlan>Advance</RoomRatePlan>
     <numeric_price>79.00</numeric_price>
     <RoomRatePlan>Standard</RoomRatePlan>
      <numeric_price>89.00</numeric_price>
     </Rate>
    </result>
    </result>
    <hotels>

I want a xslt file for the above xml output i need.please help.. 我需要上述xml输出的xslt文件,请帮助。

Muenchian method: Muenchian方法:

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes" />
    <xsl:key name="room-per-hotel" match="result" use="concat(hotel_rooms/hotel_id, '-', hotel_rooms/RoomID)" />
    <xsl:template match="/">
        <hotels>
            <xsl:for-each select="hotels/result[count(. | key('room-per-hotel', concat(hotel_rooms/hotel_id, '-', hotel_rooms/RoomID))[1]) = 1]">
                <xsl:sort select="concat(hotel_rooms/hotel_id, '-', hotel_rooms/RoomID)" />
                <result>
                    <xsl:copy-of select="hotel_rooms"/>
                    <Rate>
                        <xsl:copy-of select="key('room-per-hotel', concat(hotel_rooms/hotel_id, '-', hotel_rooms/RoomID))/Rate/*"/>
                    </Rate>
                </result>
            </xsl:for-each>
        </hotels>
    </xsl:template>
</xsl:stylesheet>

Working example 工作实例

Well neither your input nor your wanted result is well-formed with tags not being closed properly and the existence of an entity reference &pound; 嗯,您的输入或想要的结果都格式不正确,标签未正确关闭,并且存在实体引用&pound; to a not declared entity but if you want to group with XSLT 1.0 then have a look at the following XSLT 1.0 sample using Muenchian grouping : 到一个未声明的实体,但是如果要与XSLT 1.0 分组,请使用Muenchian分组查看以下XSLT 1.0示例:

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

<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="group" match="result" use="concat(hotel_rooms/hotel_id, '|', hotel_rooms/RoomID)"/>

<xsl:template match="hotels">
  <xsl:copy>
    <xsl:apply-templates select="result[generate-id() = generate-id(key('group', concat(hotel_rooms/hotel_id, '|', hotel_rooms/RoomID))[1])]"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="result">
  <xsl:copy>
    <xsl:copy-of select="hotel_rooms"/>
    <Rate>
      <xsl:copy-of select="key('group', concat(hotel_rooms/hotel_id, '|', hotel_rooms/RoomID))/Rate/*"/>
    </Rate>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

It transforms 它转变

<hotels>
 <result>
  <hotel_rooms>
    <hotel_id>6004</hotel_id>
    <NoOfNights>1</NoOfNights>
    <RoomID>1</RoomID>
    <RoomName>Double for Sole Use</RoomName>
    <RoomSize/>
    <Max_Person>1</Max_Person>
    <RackRate>189</RackRate>
    <CurrencySymbol>pound</CurrencySymbol>
    <NoOfRoomsAvailable>4</NoOfRoomsAvailable>
    <RatePerDay>27 Mar 2013_79.00</RatePerDay>
 </hotel_rooms>
 <Rate>
 <RoomRatePlan>Advance</RoomRatePlan>
 <numeric_price>79.00</numeric_price>
 </Rate>
</result>
<result>
 <hotel_rooms>
  <hotel_id>6004</hotel_id>
  <NoOfNights>1</NoOfNights>
  <RoomID>1</RoomID>
  <RoomName>Double for Sole Use</RoomName>
  <RoomSize/>
  <Max_Person>1</Max_Person>
  <RackRate>189</RackRate>
  <CurrencySymbol>pound</CurrencySymbol>
  <NoOfRoomsAvailable>5</NoOfRoomsAvailable>
  <RatePerDay>27 Mar 2013_89.00</RatePerDay>
 </hotel_rooms>
  <Rate>
  <RoomRatePlan>Standard</RoomRatePlan>
  <numeric_price>89.00</numeric_price>
  </Rate>
</result>
</hotels>

into 进入

<hotels>
  <result>
    <hotel_rooms>
      <hotel_id>6004</hotel_id>
      <NoOfNights>1</NoOfNights>
      <RoomID>1</RoomID>
      <RoomName>Double for Sole Use</RoomName>
      <RoomSize />
      <Max_Person>1</Max_Person>
      <RackRate>189</RackRate>
      <CurrencySymbol>pound</CurrencySymbol>
      <NoOfRoomsAvailable>4</NoOfRoomsAvailable>
      <RatePerDay>27 Mar 2013_79.00</RatePerDay>
    </hotel_rooms>
    <Rate>
      <RoomRatePlan>Advance</RoomRatePlan>
      <numeric_price>79.00</numeric_price>
      <RoomRatePlan>Standard</RoomRatePlan>
      <numeric_price>89.00</numeric_price>
    </Rate>
  </result>
</hotels>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM