-1

I have been working in the below conversion code for pretty long time. I am not sure the requirement is feasible in XSLT & need your help to identify whether its possible using XSLT.

My input XML is as below,

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <base:callFlowResponse xmlns:base="http://schema/webservices.elink.solcorp.com">
         <Messages>
            <More/>
         </Messages>
         <OUTPUT>
               <MIR-DV-INT>100</MIR-DV-INT>
               <MIR-DEP-AMT>0000000000042832.50</MIR-DEP-AMT>
               <MIR-DV-TOTAL-AMT-DUE>1000</MIR-DV-TOTAL-AMT-DUE>
               <MIR-MAX-REM-TOP-PREM>1000</MIR-MAX-REM-TOP-PREM>
               <MIR-DV-DUE-DT-G>
                  <TableMIR-DV-DUE-DT-T>
                     <MIR-DV-DUE-DT-T>2011-01-01</MIR-DV-DUE-DT-T>
                     <MIR-DV-DUE-DT-T/>
                     <MIR-DV-DUE-DT-T/>
                  </TableMIR-DV-DUE-DT-T>
               </MIR-DV-DUE-DT-G>
               <MIR-DV-POL-MPREM-AMT-G>
                  <TableMIR-DV-POL-MPREM-AMT-T>
                     <MIR-DV-POL-MPREM-AMT-T>1000</MIR-DV-POL-MPREM-AMT-T>
                     <MIR-DV-POL-MPREM-AMT-T/>
                     <MIR-DV-POL-MPREM-AMT-T/>
                  </TableMIR-DV-POL-MPREM-AMT-T>
               </MIR-DV-POL-MPREM-AMT-G>
               <MIR-DV-BASIC-SERV-TAX-AMT-G>
                  <TableMIR-DV-BASIC-SERV-TAX-AMT-T>
                     <MIR-DV-BASIC-SERV-TAX-AMT-T>10000</MIR-DV-BASIC-SERV-TAX-AMT-T>
                     <MIR-DV-BASIC-SERV-TAX-AMT-T/>
                     <MIR-DV-BASIC-SERV-TAX-AMT-T/>
                  </TableMIR-DV-BASIC-SERV-TAX-AMT-T>
               </MIR-DV-BASIC-SERV-TAX-AMT-G>
               <MIR-DV-TOTL-SW-CESS-AMT-G>
                  <TableMIR-DV-TOTL-SW-CESS-AMT-T>
                     <MIR-DV-TOTL-SW-CESS-AMT-T>1000</MIR-DV-TOTL-SW-CESS-AMT-T>
                     <MIR-DV-TOTL-SW-CESS-AMT-T/>
                     <MIR-DV-TOTL-SW-CESS-AMT-T/>
                  </TableMIR-DV-TOTL-SW-CESS-AMT-T>
               </MIR-DV-TOTL-SW-CESS-AMT-G>
               <MIR-DV-KR-KL-CESS-AMT-G>
                  <TableMIR-DV-KR-KL-CESS-AMT-T>
                     <MIR-DV-KR-KL-CESS-AMT-T>1000</MIR-DV-KR-KL-CESS-AMT-T>
                     <MIR-DV-KR-KL-CESS-AMT-T/>
                     <MIR-DV-KR-KL-CESS-AMT-T/>
                  </TableMIR-DV-KR-KL-CESS-AMT-T>
               </MIR-DV-KR-KL-CESS-AMT-G>
               <MIR-DV-PREM-AMT-G>
                  <TableMIR-DV-PREM-AMT-T>
                     <MIR-DV-PREM-AMT-T>10000</MIR-DV-PREM-AMT-T>
                     <MIR-DV-PREM-AMT-T/>
                     <MIR-DV-PREM-AMT-T/>
                  </TableMIR-DV-PREM-AMT-T>
               </MIR-DV-PREM-AMT-G>
               <MIR-DV-ADV-PREM-AMT>1000</MIR-DV-ADV-PREM-AMT>
               <MIR-TOTL-SW-BH-CESS-TAX-AMT>1000</MIR-TOTL-SW-BH-CESS-TAX-AMT>
               <MIR-KR-KL-CESS-TAX-AMT>1000</MIR-KR-KL-CESS-TAX-AMT>
           </OUTPUT>
      </base:callFlowResponse>
   </S:Body>
</S:Envelope>

The output XML should be as,

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <base:callFlowResponse xmlns:base="http://schema/webservices.elink.solcorp.com">
         <Messages>
            <More/>
         </Messages>
         <OUTPUT>
               <MIR-DV-INT>100</MIR-DV-INT>
               <MIR-DEP-AMT>0000000000042832.50</MIR-DEP-AMT>
               <MIR-DV-TOTAL-AMT-DUE>1000</MIR-DV-TOTAL-AMT-DUE>
               <MIR-MAX-REM-TOP-PREM>1000</MIR-MAX-REM-TOP-PREM>
               <GROUP-1>
                     <MIR-DV-DUE-DT-T>2011-01-01</MIR-DV-DUE-DT-T>
                     <MIR-DV-POL-MPREM-AMT-T>1000</MIR-DV-POL-MPREM-AMT-T>
                     <MIR-DV-BASIC-SERV-TAX-AMT-T>10000</MIR-DV-BASIC-SERV-TAX-AMT-T>
                     <MIR-DV-TOTL-SW-CESS-AMT-T>1000</MIR-DV-TOTL-SW-CESS-AMT-T>
                     <MIR-DV-KR-KL-CESS-AMT-T>1000</MIR-DV-KR-KL-CESS-AMT-T>
                     <MIR-DV-PREM-AMT-T>10000</MIR-DV-PREM-AMT-T>
               </GROUP-1>
            <GROUP-2>
                     <MIR-DV-DUE-DT-T></MIR-DV-DUE-DT-T>
                     <MIR-DV-POL-MPREM-AMT-T></MIR-DV-POL-MPREM-AMT-T>
                     <MIR-DV-BASIC-SERV-TAX-AMT-T></MIR-DV-BASIC-SERV-TAX-AMT-T>
                     <MIR-DV-TOTL-SW-CESS-AMT-T></MIR-DV-TOTL-SW-CESS-AMT-T>
                     <MIR-DV-KR-KL-CESS-AMT-T></MIR-DV-KR-KL-CESS-AMT-T>
                     <MIR-DV-PREM-AMT-T></MIR-DV-PREM-AMT-T>
               </GROUP-2>               
            <GROUP-3>
                     <MIR-DV-DUE-DT-T></MIR-DV-DUE-DT-T>
                     <MIR-DV-POL-MPREM-AMT-T></MIR-DV-POL-MPREM-AMT-T>
                     <MIR-DV-BASIC-SERV-TAX-AMT-T></MIR-DV-BASIC-SERV-TAX-AMT-T>
                     <MIR-DV-TOTL-SW-CESS-AMT-T></MIR-DV-TOTL-SW-CESS-AMT-T>
                     <MIR-DV-KR-KL-CESS-AMT-T></MIR-DV-KR-KL-CESS-AMT-T>
                     <MIR-DV-PREM-AMT-T></MIR-DV-PREM-AMT-T>
               </GROUP-3>  
               <MIR-DV-ADV-PREM-AMT>1000</MIR-DV-ADV-PREM-AMT>
               <MIR-TOTL-SW-BH-CESS-TAX-AMT>1000</MIR-TOTL-SW-BH-CESS-TAX-AMT>
               <MIR-KR-KL-CESS-TAX-AMT>1000</MIR-KR-KL-CESS-TAX-AMT>
           </OUTPUT>
      </base:callFlowResponse>
   </S:Body>
</S:Envelope>

I have seen various examples in which grouping is done on scattered nodes. But my requirement is different. I have six tables where all the related values are given like array. I have to read all the six tables element by element & create a single group. I should do this till all the nodes are read (in this case, the size is three)

It would be a great help if you could at least direct me with a similar example which i could refer for my coding.

Thanks for your help.

Rajthilak
  • 13
  • 4

1 Answers1

1

Here is an example that processes the first "table" children and collects the sibling table children in each group wrapper element:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:output indent="yes"/>

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

    <xsl:template match="OUTPUT/*[*[starts-with(local-name(), 'Table')]][1]">
        <xsl:apply-templates select="*/*" mode="group"/>
    </xsl:template>

    <xsl:template match="OUTPUT/*[*[starts-with(local-name(), 'Table')]][position() gt 1]"/>

    <xsl:template match="*" mode="group">
        <xsl:variable name="pos" select="position()"/>
        <xsl:element name="group-{position()}">
            <xsl:copy-of select="., ../../following-sibling::*[*[starts-with(local-name(), 'Table')]]/*/*[$pos]"/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

As an alternative to collect the sibling elements, you could use positional grouping:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:output indent="yes"/>

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

    <xsl:template match="OUTPUT">
        <xsl:copy>
            <xsl:for-each-group select="*" group-adjacent="boolean(self::*[*[starts-with(local-name(), 'Table')]])">
                <xsl:choose>
                    <xsl:when test="current-grouping-key()">
                        <xsl:variable name="row-count" select="count(*[1]/*)"/>
                        <xsl:for-each-group select="current-group()/*/*" group-by="position() mod $row-count">
                            <xsl:element name="GROUP-{position()}">
                                <xsl:copy-of select="current-group()"/>
                            </xsl:element>
                        </xsl:for-each-group>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:copy-of select="current-group()"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110