Re: [xsl] Issue with repetition of elements in the input XML

Subject: Re: [xsl] Issue with repetition of elements in the input XML
From: "Mukul Gandhi" <gandhi.mukul@xxxxxxxxx>
Date: Thu, 22 Nov 2007 18:14:36 +0530
This problem is easily solved with the XSLT 2.0 grouping construct.
Please refer to the solution below:

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

  <xsl:template match="/root">
    <root>
      <RCI>
        <xsl:for-each-group
select="ReservationControlInformationSegment/*"
group-starting-with="CompanyId">
          <xsl:variable name="aReservationControlInformation">RCI<xsl:number
                        value="position()" format="01"/>
          </xsl:variable>
          <xsl:element name="{$aReservationControlInformation}">
            <xsl:for-each select="current-group()">
               <xsl:variable name="aReservationControlInformationNew">
                  <xsl:value-of
select="$aReservationControlInformation" /><xsl:number
	                        value="position()" format="01"/>
               </xsl:variable>
               <xsl:element name="{$aReservationControlInformationNew}">
                 <xsl:value-of select="." />
               </xsl:element>
            </xsl:for-each>
          </xsl:element>
        </xsl:for-each-group>
      </RCI>
    </root>
  </xsl:template>

</xsl:stylesheet>

On Nov 22, 2007 3:05 PM, lakshmi mrudula <mrudula_lakshmi@xxxxxxxxx> wrote:
> Hi,
>
> We have the below issue in XSL logic. Can you please
> provide us better approach to solve the issue?
> Issue is mentioned below.
>
> If input XML has same elements that is repeating twice
> and should be mapped to the same element in the output
> XML.
>
> For Ex :
>
> If input XML is,
>
> <?xml version="1.0"?>
> <root>
> <ReservationControlInformationSegment>
> <CompanyId>AAH</CompanyId>
> <ReservationControlNumber>ABC12345</ReservationControlNumber>
> <ReservationControlType>A</ReservationControlType>
> <FirstDate>11OCT2007< /FirstDate>
> <Time>1230</Time>
> <CompanyId>AAA</CompanyId>
> <ReservationControlNumber>ABC456739</ReservationControlNumber>
> <ReservationControlType>B</ReservationControlType>
> <FirstDate>11OCT2007< /FirstDate>
> <Time>1130</Time></ReservationControlInformationSegment>
> </root>
>
>
> The expected output XML is
>
> <root>
> <RCI>
> <RCI01>
> <RCI0101>AAH</RCI0101>
> <RCI0102> ABC12345</RCI0102>
> <RCI0103>A</RCI0103>
> <RCI0104>11OCT2007</RCI0104>
> <RCI0105>1230</RCI0105>
> </RCI01>
> <RCI02>
> <RCI0201>AAA</RCI0201>
> <RCI0202>ABC456739</RCI0102>
> <RCI0203>B</RCI0103>
> <RCI0204>11OCT2007</RCI0104>
> <RCI0205>1130</RCI0105>
> </RCI02>
> </RCI>
> </root>
>
> The XSL used is as shown below
>
> <RCI>
> <xsl:for-each
> select="root/ReservationControlInformationSegment/CompanyId">
> <xsl:variable name="PositionCount"
> select="position()"/>
> <xsl:variable name="this" select="generate-id(.)"/>
> <xsl:variable name="next"
> select="generate-id(following-sibling::ReservationControlNumber[1]/preceding-sibling::CompanyId[1])"/>
> <xsl:variable name="reservationcontrolnumber">
> <xsl:if test="$this = $next">
> <xsl:value-of
> select="following-sibling::ReservationControlNumber[1]"/>
> </xsl:if>
> </xsl:variable>
> <xsl:variable name="next1"
> select="generate-id(following-sibling::ReservationControlType[1]/preceding-sibling::CompanyId[1])"/>
> <xsl:variable name="reservationcontroltype">
> <xsl:if test="$this = $next1">
> <xsl:value-of
> select="following-sibling::ReservationControlType[1]"/>
> </xsl:if>
> </xsl:variable>
> <xsl:variable name="next2"
> select="generate-id(following-sibling::FirstDate[1]/preceding-sibling::CompanyId[1])"/>
> <xsl:variable name="firstdate">
> <xsl:if test="$this = $next2">
> <xsl:value-of
> select="following-sibling::FirstDate[1]"/>
> </xsl:if>
> </xsl:variable>
> <xsl:variable name="next3"
> select="generate-id(following-sibling::Time[1]/preceding-sibling::CompanyId[1])"/>
> <xsl:variable name="time">
> <xsl:if test="$this = $next3">
> <xsl:value-of select="following-sibling::Time[1]"/>
> </xsl:if>
> </xsl:variable>
> <xsl:variable
> name="aReservationControlInformation">RCI<xsl:number
> value="position()" format="01"/></xsl:variable>
> <xsl:element name="{$aReservationControlInformation}">
> <xsl:variable name="aCompanyId">RCI<xsl:number
> value="position()" format="01"/>01</xsl:variable>
> <xsl:element name="{$aCompanyId}">
> <xsl:value-of select="."/>
> </xsl:element>
> <xsl:variable
> name="aReservationControlNumber">RCI<xsl:number
> value="position()" format="01"/>02</xsl:variable>
> <xsl:element name="{$aReservationControlNumber}">
> <xsl:value-of select="$reservationcontrolnumber"/>
> </xsl:element>
> <xsl:variable
> name="aReservationControlType">RCI<xsl:number
> value="position()" format="01"/>03</xsl:variable>
> <xsl:if
> test="following-sibling::ReservationControlType[1][normalize-space()]">
> <xsl:element name="{$aReservationControlType}">
> <xsl:value-of select="$reservationcontroltype"/>
> </xsl:element>
> </xsl:if>
> <xsl:variable name="aFirstDate">RCI<xsl:number
> value="position()" format="01"/>04</xsl:variable>
> <xsl:if
> test="following-sibling::FirstDate[1][normalize-space()]">
> <xsl:element name="{$aFirstDate}">
> <xsl:value-of select="$firstdate"/>
> </xsl:element>
> </xsl:if>
> <xsl:variable name="aTime">RCI<xsl:number
> value="position()" format="01"/>05</xsl:variable>
> <xsl:if
> test="following-sibling::Time[1][normalize-space()]">
> <xsl:element name="{$aTime}">
> <xsl:value-of select="$time"/>
> </xsl:element>
> </xsl:if>
> </xsl:element>
> </xsl:for-each>
> </RCI>
>
> It works fine when all the elements are there.
>
> But if any of the elements in the input is missing,
> then there is a problem.
> In input XML, elements will be in the same order. None
> of the elements are mandatory.
> Any of the elements can be missed in the input XML.
>
> Our requirement for the output is:
>
> If any information is missing in the middle then empty
> tag should be there.
> But if it is missing at the end, then empty tags need
> not be there in the output.
>
> For Ex:
>
> If in the second repetition, ReservationControlNumber
> is missing
>
> <?xml version="1.0"?>
> <root>
> <ReservationControlInformationSegment>
> <CompanyId>AAH</CompanyId>
> <ReservationControlNumber>ABC12345</ReservationControlNumber>
> <ReservationControlType>A</ReservationControlType>
> <FirstDate>11OCT2007< /FirstDate>
> <Time>1230</Time>
> <CompanyId>AAA</CompanyId>
>
> <ReservationControlType>B</ReservationControlType>
> <FirstDate>11OCT2007< /FirstDate>
> <Time>1130</Time></ReservationControlInformationSegment>
> </root>
>
>
>
>
>
> Then output should be
>
> <root>
> <RCI>
> <RCI01>
> <RCI0101>AAH</RCI0101>
> <RCI0102> ABC12345</RCI0102>
> <RCI0103>A</RCI0103>
> <RCI0104>11OCT2007</RCI0104>
> <RCI0105>1230</RCI0105>
> </RCI01>
> <RCI02>
> <RCI0201>AAA</RCI0201>
> <RCI0202/>
>  <RCI0203>B</RCI0103>
> <RCI0204>11OCT2007</RCI0104>
> <RCI0205>1130</RCI0105>
> </RCI02>
> </RCI>
> </root>
>
> ReservationControlNumber is missing in the middle. So
> to keep the message order properly. It should come
> with an empty tag. If any element is missing at the
> end, then that element information need not present in
> the output.
>
> For ex if input XML is as below:
>
> <?xml version="1.0"?>
> <root>
> <ReservationControlInformationSegment>
> <CompanyId>AAH</CompanyId>
> <ReservationControlNumber>ABC12345</ReservationControlNumber>
> <ReservationControlType>A</ReservationControlType>
> <FirstDate>11OCT2007< /FirstDate>
> <Time>1230</Time>
> <CompanyId>AAA</CompanyId>
> <ReservationControlNumber>ABC56789</ReservationControlNumber>
> <ReservationControlType>B</ReservationControlType>
> </root>
>
> Output should be:
> <root>
> <RCI>
> <RCI01>
> <RCI0101>AAH</RCI0101>
> <RCI0102> ABC12345</RCI0102>
> <RCI0103>A</RCI0103>
> <RCI0104>11OCT2007</RCI0104>
> <RCI0105>1230</RCI0105>
> </RCI01>
> <RCI02>
> <RCI0201>AAA</RCI0201>
> <RCI0202> ABC56789</RCI0202>
>  <RCI0203>B</RCI0103>
> </RCI02>
> </RCI>
> </root>
>
> In the input, FirstDate and Time are missing in the
> second repetition. Since those elements are present at
> the end, empty tags are not needed in the output.
>
> But with the XSL logic we have mentioned above, this
> is not happening. Empty tags are coming at the end.
>
> Can you please provide us better approach to solve
> this issue?


-- 
Regards,
Mukul Gandhi

Current Thread