Search code examples
excelxmlxslt-1.0xslt-2.0xpath-2.0

how to access variable structure under for-each to create excel sheet in XSLT


I have input like:

<item id="CON_1985_14">
   <prv id="p1">
      <no>1</no>
      <text>This &quot;May&quot; take some moment, you &quot;shall&quot; not go there.</text>
      <text>This is ok.</text>
   </prv>
</item>

Need to create a excel table on the basis of quoted values.

=========================
A                 B
=========================
May           CON_1985_14
shall         CON_1985_14
=========================

Created XSLT to generate excel output like:

<Worksheet ss:Name="R6">
   <Table>
      <Row>
         <Cell>
            <Data ss:Type="String">
               <xsl:text>A</xsl:text>
            </Data>
         </Cell>
         <Cell>
            <Data ss:Type="String">
               <xsl:text>B</xsl:text>
            </Data>
         </Cell>
      </Row>
      <xsl:for-each select="$path">
         <xsl:for-each select="descendant::prv//descendant::text">
            <xsl:variable name="STRUCTUREONBASISOFTOKENS" as="node()">
               <Report>
                  <dd>
                     <xsl:for-each select="tokenize(normalize-space(.), '(&quot;|&#x201C;)')">
                        <xsl:if test="(position() gt 1) and (position() mod 2 = 0)">
                           <xsl:value-of select="normalize-space(.)"/>
                           <xsl:if test="position() ne (last() - 1)">
                              <xsl:text>, </xsl:text>
                           </xsl:if>
                        </xsl:if>
                     </xsl:for-each>
                  </dd>
                  <LID>
                     <xsl:value-of select="/item/@id"/>
                  </LID>
               </Report>
            </xsl:variable>

            <xsl:for-each select="tokenize($STRUCTUREONBASISOFTOKENS/Report/dd, ',')">
               <Row>
                  <Cell>
                     <Data ss:Type="String">
                        <xsl:value-of select="normalize-space(.)"/>
                     </Data>
                  </Cell>
                  <Cell>
                     <Data ss:Type="String">
                        <xsl:value-of select="$STRUCTUREONBASISOFTOKENS/Report/LID"/>
                     </Data>
                  </Cell>
               </Row>
            </xsl:for-each>
         </xsl:for-each>
      </xsl:for-each>
   </Table>
</Worksheet>

The variable created inside for-each having output printed in message like:

<Report xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:LxNx="http://www.LXNX.com"
   xmlns="urn:schemas-microsoft-com:office:spreadsheet"
   xmlns:dict="http://www.lexis-nexis.com/glp/dict" xmlns:ci="http://www.lexis-nexis.com/ci"
   xmlns:o="urn:schemas-microsoft-com:office:office"
   xmlns:x="urn:schemas-microsoft-com:office:excel"
   xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
   <dd>May, shall</dd>
   <LID>CON_1985_14</LID>
</Report>

Now the nested for-each, just below the variable define is trying to fetch the values from the variable structure to generate the ROWs, but not succeed.. Not able to fetch the values from the variable by xpath to generate row. This syntax '' means the collection() path.

Provide the suitable solution for that.


Solution

  • I could not follow the logic of your attempted XSLT. Consider the following simplified example:

    XML

    <input>
        <item>Lorem ipsum "alpha" dolor sit amet, consectetur "bravo" adipiscing elit "charlie".</item>
        <item>"Delta" sed do eiusmod tempor "echo" incididunt ut labore et dolore magna aliqua.</item>
    </input>
    

    XSLT 2.0

    <xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:template match="/input">
        <table>
            <xsl:for-each select="item">
                <xsl:analyze-string select="." regex="&quot;(.*?)&quot;">
                    <xsl:matching-substring>
                        <row>
                            <cell>
                                <xsl:value-of select="regex-group(1)" />
                            </cell>
                        </row>
                    </xsl:matching-substring>
                </xsl:analyze-string>
            </xsl:for-each>
        </table>
    </xsl:template>
    
    </xsl:stylesheet>
    

    Result

    <?xml version="1.0" encoding="UTF-8"?>
    <table>
       <row>
          <cell>alpha</cell>
       </row>
       <row>
          <cell>bravo</cell>
       </row>
       <row>
          <cell>charlie</cell>
       </row>
       <row>
          <cell>Delta</cell>
       </row>
       <row>
          <cell>echo</cell>
       </row>
    </table>
    

    Demo: https://xsltfiddle.liberty-development.net/6rewNy4