簡體   English   中英

在XSLT中合並相同的子元素

[英]Combine identical child elements in XSLT

大家好,首先,我正在學習復雜的XSLT迭代並編寫,現在我陷入了一個查詢中,在該查詢中,我在“標簽信息”下擁有相同的信息,而唯一不同的標簽是“ BookingClassAvail”,具有不同的屬性值,我想合並為一個保留信息標記為單獨的。

XML:

      <Availability>
        <Success/>
        <Information xmlns="http://www.opentravel.org/OTA/2003/05">
          <DepDateTime>2012-10-27</DepDateTime>
          <OrigLocation LocationCode="DEL" />
          <DestLocation LocationCode="BOM" />
          <OrigDestinationOptions>
            <OrigDestinationOption>
              <FlightSegment DepDateTime="2012-10-27A12:35:00" ArrDateTime="2012-10-27A14:05:00" StopQuantity="0" FlightNumber="152" JourneyDuration="90" Ticket="eTicket">
                <DepAirport LocationCode="DEL" Terminal="" />
                <ArrAirport LocationCode="BOM" Terminal="" />
                <OperatingAirline CompanyShortName="A1" />
                <Equipment AirEquipType="A320" />
                <MarketingAirline CompanyShortName="A1" />
                <BookingClassAvail ResBookDesigCode="T" ResBookDesigQuantity="180" />
              </FlightSegment>
            </OrigDestinationOption>
            <OrigDestinationOption>
              <FlightSegment DepDateTime="2012-10-27A12:35:00" ArrDateTime="2012-10-27A14:05:00" StopQuantity="0" FlightNumber="152" JourneyDuration="90" Ticket="eTicket">
                <DepAirport LocationCode="DEL" Terminal="" />
                <ArrAirport LocationCode="BOM" Terminal="" />
                <OperatingAirline CompanyShortName="A1" />
                <Equipment AirEquipType="A320" />
                <MarketingAirline CompanyShortName="A1" />
                <BookingClassAvail ResBookDesigCode="B" ResBookDesigQuantity="80" />
              </FlightSegment>
            </OrigDestinationOption>


            <OrigDestinationOption>
              <FlightSegment DepDateTime="2012-10-28A10:35:00" ArrDateTime="2012-10-27A14:05:00" StopQuantity="0" FlightNumber="152" JourneyDuration="90" Ticket="eTicket">
                <DepAirport LocationCode="DEL" Terminal="" />
                <ArrAirport LocationCode="BOM" Terminal="" />
                <OperatingAirline CompanyShortName="A1" />
                <Equipment AirEquipType="A320" />
                <MarketingAirline CompanyShortName="A1" />
                <BookingClassAvail ResBookDesigCode="B" ResBookDesigQuantity="80" />
              </FlightSegment>
            </OrigDestinationOption>
          </OrigDestinationOptions>
        </Information>
        <Information xmlns="http://www.opentravel.org/OTA/2003/05">
          <DepDateTime>2012-11-05</DepDateTime>
          <OrigLocation LocationCode="BOM" />
          <DestinationLocation LocationCode="DEL" />
          <OrigDestinationOptions>
            <OrigDestinationOption>
              <FlightSegment DepDateTime="2012-11-05T08:35:00" ArrDateTime="2012-11-05T09:40:00" StopQuantity="0" FlightNumber="993" JourneyDuration="65" Ticket="eTicket">
                <DepAirport LocationCode="BOM" Terminal="" />
                <ArrAirport LocationCode="DEL" Terminal="" />
                <OperatingAirline CompanyShortName="GR" />
                <Equipment AirEquipType="A320" />
                <MarketingAirline CompanyShortName="GR" />
                <BookingClassAvail ResBookDesigCode="T" ResBookDesigQuantity="180" />
              </FlightSegment>
            </OrigDestinationOption>
            <OrigDestinationOption>
              <FlightSegment DepDateTime="2012-11-05A08:35:00" ArrDateTime="2012-11-05A16:15:00" StopQuantity="0" FlightNumber="666" JourneyDuration="75" Ticket="eTicket">
                <DepAirport LocationCode="BOM" Terminal="" />
                <ArrAirport LocationCode="DEL" Terminal="" />
                <OperatingAirline CompanyShortName="MM" />
                <Equipment AirEquipType="A320" />
                <MarketingAirline CompanyShortName="MM" />
                <BookingClassAvail ResBookDesigCode="Y" ResBookDesigQuantity="180" />
              </FlightSegment>
            </OrigDestinationOption>
          </OrigDestinationOptions>
        </Information>
      </Availability>

想要如下所示的輸出:

    <Availability>
      <Success/>
      <Information xmlns="http://www.opentravel.org/OTA/2003/05">
        <DepDateTime>2012-10-27</DepDateTime>
        <OrigLocation LocationCode="DEL" />
        <DestLocation LocationCode="BOM" />
        <OrigDestinationOptions>
          <OrigDestinationOption>
            <FlightSegment DepDateTime="2012-10-27A12:35:00" ArrDateTime="2012-10-27A14:05:00" StopQuantity="0" FlightNumber="152" JourneyDuration="90" Ticket="eTicket">
              <DepAirport LocationCode="DEL" Terminal="" />
              <ArrAirport LocationCode="BOM" Terminal="" />
              <OperatingAirline CompanyShortName="A1" />
              <Equipment AirEquipType="A320" />
              <MarketingAirline CompanyShortName="A1" />
              <BookingClassAvail ResBookDesigCode="T" ResBookDesigQuantity="180" />
              <BookingClassAvail ResBookDesigCode="B" ResBookDesigQuantity="80" />
            </FlightSegment>
          </OrigDestinationOption>

         <!-- since the DepDateTime has different date hence not combined in the above flightsegment -->

            <OrigDestinationOption>
              <FlightSegment DepDateTime="2012-10-28A10:35:00" ArrDateTime="2012-10-27A14:05:00" StopQuantity="0" FlightNumber="152" JourneyDuration="90" Ticket="eTicket">
                <DepAirport LocationCode="DEL" Terminal="" />
                <ArrAirport LocationCode="BOM" Terminal="" />
                <OperatingAirline CompanyShortName="A1" />
                <Equipment AirEquipType="A320" />
                <MarketingAirline CompanyShortName="A1" />
                <BookingClassAvail ResBookDesigCode="B" ResBookDesigQuantity="80" />
              </FlightSegment>
            </OrigDestinationOption>
        </OrigDestinationOptions>
      </Information>
      <Information xmlns="http://www.opentravel.org/OTA/2003/05">
        <DepDateTime>2012-11-05</DepDateTime>
        <OrigLocation LocationCode="BOM" />
        <DestinationLocation LocationCode="DEL" />
        <OrigDestinationOptions>
          <OrigDestinationOption>
            <FlightSegment DepDateTime="2012-11-05T08:35:00" ArrDateTime="2012-11-05T09:40:00" StopQuantity="0" FlightNumber="993" JourneyDuration="65" Ticket="eTicket">
              <DepAirport LocationCode="BOM" Terminal="" />
              <ArrAirport LocationCode="DEL" Terminal="" />
              <OperatingAirline CompanyShortName="GR" />
              <Equipment AirEquipType="A320" />
              <MarketingAirline CompanyShortName="GR" />
              <BookingClassAvail ResBookDesigCode="T" ResBookDesigQuantity="180" />
              <BookingClassAvail ResBookDesigCode="Y" ResBookDesigQuantity="180" />
            </FlightSegment>
          </OrigDestinationOption>
        </OrigDestinationOptions>
      </Information>
    </Availability>

如果在標簽上方看到,BookingClassAvail的ResBookDesigCode和ResBookDesigQuantity信息不同,因此需要逐行堆疊。

<BookingClassAvail ResBookDesigCode="T" ResBookDesigQuantity="180" />
<BookingClassAvail ResBookDesigCode="B" ResBookDesigQuantity="80" />

同樣,如果輸入的任何信息與應該作為單獨的航段一起出現的信息不同。

還要注意,上面一個標簽是用於外航航班的標簽,而其他信息則是在用於進站航班的標簽上,因此需要單獨保存,並且只需要合並即可。

預先感謝一百萬。


肖恩(Sean)我使用了建議的解決方案,並且遇到一個錯誤,因為“無法從已經加載的輸入文檔中剝離空白。請改為以XmlReader的形式提供輸入文檔。”

XML:

        <Availability>
  <Success/>
  <Information xmlns="http://www.opentravel.org/OTA/2003/05">
    <DepDateTime>2012-10-27</DepDateTime>
    <OrigLocation LocationCode="DEL" />
    <DestinationLocation LocationCode="BOM" />
    <OrigDestinationOptions>
      <OrigDestinationOption>
        <FlightSegment DepDateTime="2012-10-27T12:35:00" ArrivalDateTime="2012-10-27T14:05:00" StopQuantity="0" FlightNumber="152" JourneyDuration="90" Ticket="eTicket">
          <DepAirport LocationCode="DEL" Terminal="" />
          <ArrivalAirport LocationCode="BOM" Terminal="" />
          <OperatingAirline CompanyShortName="A1" />
          <Equipment AirEquipType="A123" />
          <MarketingAirline CompanyShortName="A1" />
          <BookingClassAvail ResBookDesigCode="O" ResBookDesigQuantity="40" />
        </FlightSegment>
      </OrigDestinationOption>
      <OrigDestinationOption>
        <FlightSegment DepDateTime="2012-10-27T12:35:00" ArrivalDateTime="2012-10-27T14:05:00" StopQuantity="0" FlightNumber="152" JourneyDuration="90" Ticket="eTicket">
          <DepAirport LocationCode="DEL" Terminal="" />
          <ArrivalAirport LocationCode="BOM" Terminal="" />
          <OperatingAirline CompanyShortName="A1" />
          <Equipment AirEquipType="A123" />
          <MarketingAirline CompanyShortName="A1" />
          <BookingClassAvail ResBookDesigCode="T" ResBookDesigQuantity="180" />
        </FlightSegment>
      </OrigDestinationOption>
      <OrigDestinationOption>
        <FlightSegment DepDateTime="2012-10-27T19:10:00" ArrivalDateTime="2012-10-27T20:10:00" StopQuantity="0" FlightNumber="158" JourneyDuration="60" Ticket="eTicket">
          <DepAirport LocationCode="DEL" Terminal="" />
          <ArrivalAirport LocationCode="BOM" Terminal="" />
          <OperatingAirline CompanyShortName="A1" />
          <Equipment AirEquipType="A123" />
          <MarketingAirline CompanyShortName="A1" />
          <BookingClassAvail ResBookDesigCode="D" ResBookDesigQuantity="50" />
        </FlightSegment>
      </OrigDestinationOption>
    </OrigDestinationOptions>
  </Information>
  <Information xmlns="http://www.opentravel.org/OTA/2003/05">
    <DepDateTime>2012-11-05</DepDateTime>
    <OrigLocation LocationCode="BOM" />
    <DestinationLocation LocationCode="DEL" />
    <OrigDestinationOptions>
      <OrigDestinationOption>
        <FlightSegment DepDateTime="2012-11-05T15:00:00" ArrivalDateTime="2012-11-05T16:15:00" StopQuantity="0" FlightNumber="666" JourneyDuration="75" Ticket="eTicket">
          <DepAirport LocationCode="BOM" Terminal="" />
          <ArrivalAirport LocationCode="DEL" Terminal="" />
          <OperatingAirline CompanyShortName="M1" />
          <Equipment AirEquipType="A123" />
          <MarketingAirline CompanyShortName="M1" />
          <BookingClassAvail ResBookDesigCode="Y" ResBookDesigQuantity="180" />
        </FlightSegment>
      </OrigDestinationOption>
      <OrigDestinationOption>
        <FlightSegment DepDateTime="2012-11-05T15:00:00" ArrivalDateTime="2012-11-05T16:15:00" StopQuantity="0" FlightNumber="666" JourneyDuration="75" Ticket="eTicket">
          <DepAirport LocationCode="BOM" Terminal="" />
          <ArrivalAirport LocationCode="DEL" Terminal="" />
          <OperatingAirline CompanyShortName="M1" />
          <Equipment AirEquipType="A123" />
          <MarketingAirline CompanyShortName="M1" />
          <BookingClassAvail ResBookDesigCode="Y" ResBookDesigQuantity="180" />
        </FlightSegment>
      </OrigDestinationOption>
    </OrigDestinationOptions>
  </Information>
</Availability>

使用的XSLT:

     <xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:ot="http://www.opentravel.org/OTA/2003/05"
  exclude-result-prefixes="xsl ot">
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*" />

  <xsl:key name="kSegment" match="ot:OrigDestinationOption"
                           use="concat( ot:FlightSegment[1]/@DepDateTime,
                                          '|', generate-id(..))" />

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="ot:OrigDestinationOptions">
    <xsl:variable name="options" select="generate-id()" />
    <xsl:copy>
      <xsl:apply-templates select="
     ot:OrigDestinationOption[
       generate-id()=generate-id(key('kSegment',
        concat( ot:FlightSegment[1]/@DepDateTime,
                '|', $options))[1])]" mode="group" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="ot:OrigDestinationOption" mode="group">
    <xsl:variable name="group" select="key('kSegment',
        concat( ot:FlightSegment[1]/@DepDateTime,'|', generate-id(..)))" />
    <xsl:copy>
      <xsl:apply-templates select="*[not(self::ot:FlightSegment)]"/>
      <FlightSegment xmlns="http://www.opentravel.org/OTA/2003/05">
        <xsl:apply-templates
          select="ot:FlightSegment[1]/@*  |
               ot:FlightSegment[1]/*[not(self::ot:BookingClassAvail)] |
               $group/ot:FlightSegment/ot:BookingClassAvail" />
      </FlightSegment>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

遇到錯誤:

“不能從已經加載的輸入文檔中剝離空格。而應將輸入文檔作為XmlReader提供。”

此XSLT 1.0樣式表...

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:ot="http://www.opentravel.org/OTA/2003/05"
  exclude-result-prefixes="xsl ot">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*" />

    <xsl:key name="kSegment" match="ot:OrigDestinationOption"
                             use="concat( ot:FlightSegment[1]/@DepDateTime,
                                          '|', generate-id(..))" />

<xsl:template match="@*|node()">
 <xsl:copy>
   <xsl:apply-templates select="@*|node()"/>
 </xsl:copy>
</xsl:template>

<xsl:template match="ot:OrigDestinationOptions">
 <xsl:variable name="options" select="generate-id()" />
 <xsl:copy>
   <xsl:apply-templates select="
     ot:OrigDestinationOption[
       generate-id()=generate-id(key('kSegment',
        concat( ot:FlightSegment[1]/@DepDateTime,
                '|', $options))[1])]" mode="group" />
 </xsl:copy>
</xsl:template>

<xsl:template match="ot:OrigDestinationOption" mode="group">
  <xsl:variable name="group" select="key('kSegment',
        concat( ot:FlightSegment[1]/@DepDateTime,'|', generate-id(..)))" /> 
 <xsl:copy>
   <xsl:apply-templates select="*[not(self::ot:FlightSegment)]"/>
   <FlightSegment xmlns="http://www.opentravel.org/OTA/2003/05">
     <xsl:apply-templates
       select="ot:FlightSegment[1]/@*  |
               ot:FlightSegment[1]/*[not(self::ot:BookingClassAvail)] |
               $group/ot:FlightSegment/ot:BookingClassAvail" />
   </FlightSegment>  
 </xsl:copy>
</xsl:template>

</xsl:stylesheet>

...應用於此輸入時 (OP提供的文檔的簡化版本)...

<Availability>
    <Information xmlns="http://www.opentravel.org/OTA/2003/05">
    <OrigDestinationOptions>
        <OrigDestinationOption>
            <FlightSegment DepDateTime="2012-10-27A12:35:00" Ticket="eTicket">
                <DepAirport LocationCode="DEL" Terminal=""/>
                <BookingClassAvail ResBookDesigCode="T" ResBookDesigQuantity="180"/>
            </FlightSegment>
        </OrigDestinationOption>
        <OrigDestinationOption>
            <FlightSegment DepDateTime="2012-10-27A12:35:00" Ticket="eTicket">
                <DepAirport LocationCode="DEL" Terminal=""/>
                <BookingClassAvail ResBookDesigCode="B" ResBookDesigQuantity="80"/>
            </FlightSegment>
        </OrigDestinationOption>
    </OrigDestinationOptions>
</Information>
<Information xmlns="http://www.opentravel.org/OTA/2003/05">
<OrigDestinationOptions>
    <OrigDestinationOption>
        <FlightSegment DepDateTime="2012-10-28A10:35:00" Ticket="eTicket">
            <DepAirport LocationCode="DEL" Terminal=""/>
            <BookingClassAvail ResBookDesigCode="B" ResBookDesigQuantity="80"/>
        </FlightSegment>
    </OrigDestinationOption>
</OrigDestinationOptions>
</Information>
</Availability>

產量

<Availability>
  <Information xmlns="http://www.opentravel.org/OTA/2003/05">
    <OrigDestinationOptions>
      <OrigDestinationOption>
        <FlightSegment DepDateTime="2012-10-27A12:35:00" Ticket="eTicket">
          <DepAirport LocationCode="DEL" Terminal="" />
          <BookingClassAvail ResBookDesigCode="T" ResBookDesigQuantity="180" />
          <BookingClassAvail ResBookDesigCode="B" ResBookDesigQuantity="80" />
        </FlightSegment>
      </OrigDestinationOption>
    </OrigDestinationOptions>
  </Information>
  <Information xmlns="http://www.opentravel.org/OTA/2003/05">
    <OrigDestinationOptions>
      <OrigDestinationOption>
        <FlightSegment DepDateTime="2012-10-28A10:35:00" Ticket="eTicket">
          <DepAirport LocationCode="DEL" Terminal="" />
          <BookingClassAvail ResBookDesigCode="B" ResBookDesigQuantity="80" />
        </FlightSegment>
      </OrigDestinationOption>
    </OrigDestinationOptions>
  </Information>
</Availability>

筆記

  1. 分組鍵是父OrigDestinationOptions節點與航班起飛時間的乘積。
  2. 假定每個OrigDestinationOption恰好包含一個FlightSegment。
  3. 假設要合並同一組中的FlightSegments,則需要保留的該組所有成員上唯一不同的信息是BookingClassAvail元素。
  4. 這不是一個超通用的解決方案,但是考慮到問題表達中缺乏定義,這是合理的。 如果需要更通用的解決方案,則需要更精確地了解輸入結構和轉換規則。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM