[xsl] comparing following nodes and re-structuring.

Subject: [xsl] comparing following nodes and re-structuring.
From: charlieo0@xxxxxxxxxxx
Date: Tue, 6 Dec 2011 14:17:12 +0000 (UTC)
I could use some help with the following problem.

I have an XML instance that is a long list of table entries. I need to compare text nodes and if they are the same, restructure an aspect of the row. I have been able to write something that will compare only the first following and first preceding rows, but I need to be able to traverse multiple rows until the matching stops. If there is no duplicate NSN, then merely copy the row as is.



A sample of the input:

   <nsnindx>
      <nsnindxrow>
         <nsn>
            <fsc>5905</fsc>
            <niin>00-004-6116</niin>
         </nsn>
         <callout assocfig="P4503692350366-FIG026" label="36"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>5905</fsc>
            <niin>00-004-6116</niin>
         </nsn>
         <callout assocfig="P4502792350366-FIG017" label="36"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>5905</fsc>
            <niin>00-004-6117</niin>
         </nsn>
         <callout assocfig="P4503692350366-FIG026" label="36"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>5905</fsc>
            <niin>00-004-6117</niin>
         </nsn>
         <callout assocfig="P4502792350366-FIG017" label="36"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>5905</fsc>
            <niin>00-004-6120</niin>
         </nsn>
         <callout assocfig="P4503692350366-FIG026" label="36"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>5905</fsc>
            <niin>00-004-6120</niin>
         </nsn>
         <callout assocfig="P4502792350366-FIG017" label="36"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>6145</fsc>
            <niin>00-013-8651</niin>
         </nsn>
         <callout assocfig="P4505792350366-FIGBULK" label="42"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>5310</fsc>
            <niin>00-014-5850</niin>
         </nsn>
         <callout assocfig="P4500292350366-FIG001" label="17"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>5310</fsc>
            <niin>00-014-5850</niin>
         </nsn>
         <callout assocfig="P4500892350366-FIG007" label="30"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>5310</fsc>
            <niin>00-014-5850</niin>
         </nsn>
         <callout assocfig="P4501892350366-FIG046" label="7"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>5310</fsc>
            <niin>00-014-5850</niin>
         </nsn>
         <callout assocfig="P4502292350366-FIG032" label="9"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>5310</fsc>
            <niin>00-045-3296</niin>
         </nsn>
         <callout assocfig="P4503892350366-FIG027" label="19"/>
      </nsnindxrow>
   </nsnindx>

The desired output:


   <nsnindx>
      <nsnindxrow>
         <nsn>
            <fsc>5905</fsc>
            <niin>00-004-6116</niin>
         </nsn>
         <callout assocfig="P4503692350366-FIG026" label="36"/>
         <callout assocfig="P4502792350366-FIG017" label="36"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>5905</fsc>
            <niin>00-004-6117</niin>
         </nsn>
         <callout assocfig="P4503692350366-FIG026" label="36"/>
           <callout assocfig="P4502792350366-FIG017" label="36"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>5905</fsc>
            <niin>00-004-6120</niin>
         </nsn>
         <callout assocfig="P4503692350366-FIG026" label="36"/>
         <callout assocfig="P4502792350366-FIG017" label="36"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>6145</fsc>
            <niin>00-013-8651</niin>
         </nsn>
         <callout assocfig="P4505792350366-FIGBULK" label="42"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>5310</fsc>
            <niin>00-014-5850</niin>
         </nsn>
         <callout assocfig="P4500292350366-FIG001" label="17"/>
          <callout assocfig="P4500892350366-FIG007" label="30"/>
          <callout assocfig="P4501892350366-FIG046" label="7"/>
        <callout assocfig="P4502292350366-FIG032" label="9"/>
      </nsnindxrow>
      <nsnindxrow>
         <nsn>
            <fsc>5310</fsc>
            <niin>00-045-3296</niin>
         </nsn>
         <callout assocfig="P4503892350366-FIG027" label="19"/>
      </nsnindxrow>
   </nsnindx>

What I have so far is:

    <xsl:template match="nsnindx">
       <nsnindx>
        <xsl:for-each select="child::nsnindxrow">
            
                <xsl:variable name="full_NSN">
                    <xsl:value-of select="concat(descendant::fsc,descendant::niin)"/>
                </xsl:variable>
                 <xsl:choose>
                     <xsl:when test="$full_NSN = concat(following-sibling::nsnindxrow[1]/descendant::fsc,following-sibling::nsnindxrow[1]/descendant::niin)">
                        <nsnindxrow>
                            <xsl:copy-of select="child::nsn"/>
                            <xsl:copy-of select="child::callout"/>
                          <xsl:copy-of select="following-sibling::nsnindxrow[1]//callout"/>
                        </nsnindxrow>
                    </xsl:when>
                     <xsl:when test="$full_NSN = concat(following-sibling::nsnindxrow[1]/descendant::fsc,preceding-sibling::nsnindxrow[1]/descendant::niin)"/>
                     <xsl:otherwise>
                         <nsnindxrow>
                            <xsl:copy-of select="child::nsn"/>
                            <xsl:copy-of select="child::callout"/>
                         </nsnindxrow>
                     </xsl:otherwise>
            </xsl:choose>
            
        </xsl:for-each>
        </nsnindx>
    </xsl:template>

This work fine if there are only two successive entries where the NSNs match. However, there can certainly be more than two in a row that match (see input). How do I progess through each <nsnindxrow>, rebuild the row, until the matching stops?

Thanks.

C Flanders

Current Thread