xmlxslt-2.0xsl-fopolarion

Generate table in XSL from XML


i want to make an XSL file to generate PDF`s with it.

         <values>
            <item>
              <html>
                <p xmlns="http://www.w3.org/1999/xhtml">Step</p>
              </html>
            </item>
            <item>
              <html>
                <p xmlns="http://www.w3.org/1999/xhtml">Description</p>
              </html>
            </item>
            <item>
              <html>
                <p xmlns="http://www.w3.org/1999/xhtml">Result</p>
              </html>
            </item>
          </values>

No i want to represent this my PDF as Table, but i dont get how to implement it in my existing file.

The Result should look like this

Im really new in XSL and i hope some can help to solve this problem.

Many greetings


Solution

  • A minimal sample to transform that XML snippet into an XSL-FO table is

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:fo="http://www.w3.org/1999/XSL/Format"
        xmlns:xhtml="http://www.w3.org/1999/xhtml"
        exclude-result-prefixes="fo xhtml"
        version="3.0">
    
    <xsl:output indent="yes"/>
    
    <xsl:template match="/">
        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
            <fo:layout-master-set>
                <fo:simple-page-master master-name="sample">
                    <fo:region-body/>
                </fo:simple-page-master>
            </fo:layout-master-set>
            <fo:page-sequence master-reference="sample">
                <fo:flow flow-name="xsl-region-body">
                    <fo:block>
                        <xsl:apply-templates/>
                    </fo:block>
                </fo:flow>
            </fo:page-sequence>
        </fo:root>
    
    </xsl:template>
    
    <xsl:template match="values">
        <fo:table>
            <fo:table-column column-width="*"/>
            <fo:table-column column-width="*"/>
            <fo:table-column column-width="*"/>
            <fo:table-header>
              <fo:table-row>
                <fo:table-cell>
                  <fo:block font-weight="bold">Step</fo:block>
                </fo:table-cell>
                <fo:table-cell>
                  <fo:block font-weight="bold">Step description</fo:block>
                </fo:table-cell>
                <fo:table-cell>
                  <fo:block font-weight="bold">Expected result</fo:block>
                </fo:table-cell>
              </fo:table-row>
            </fo:table-header>
    
            <fo:table-body>
              <fo:table-row>
                  <xsl:apply-templates/>
              </fo:table-row>
            </fo:table-body>
        </fo:table>
    </xsl:template>
    
    <xsl:template match="item">
       <fo:table-cell>
          <fo:block>
              <xsl:value-of select="html/xhtml:p"/>
          </fo:block>
        </fo:table-cell>
    </xsl:template>
    
    </xsl:stylesheet>
    

    At https://xsltfiddle.liberty-development.net/gWmuiJ4 that transforms your input snippet into the FO

    <?xml version="1.0" encoding="UTF-8"?>
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
       <fo:layout-master-set>
          <fo:simple-page-master master-name="sample">
             <fo:region-body/>
          </fo:simple-page-master>
       </fo:layout-master-set>
       <fo:page-sequence master-reference="sample">
          <fo:flow flow-name="xsl-region-body">
             <fo:block>
                <fo:table>
                   <fo:table-column column-width="*"/>
                   <fo:table-column column-width="*"/>
                   <fo:table-column column-width="*"/>
                   <fo:table-header>
                      <fo:table-row>
                         <fo:table-cell>
                            <fo:block font-weight="bold">Step</fo:block>
                         </fo:table-cell>
                         <fo:table-cell>
                            <fo:block font-weight="bold">Step description</fo:block>
                         </fo:table-cell>
                         <fo:table-cell>
                            <fo:block font-weight="bold">Expected result</fo:block>
                         </fo:table-cell>
                      </fo:table-row>
                   </fo:table-header>
                   <fo:table-body>
                      <fo:table-row>
                         <fo:table-cell>
                            <fo:block> i am a step</fo:block>
                         </fo:table-cell>
                         <fo:table-cell>
                            <fo:block>i am a desc</fo:block>
                         </fo:table-cell>
                         <fo:table-cell>
                            <fo:block>i am a res</fo:block>
                         </fo:table-cell>
                      </fo:table-row>
                   </fo:table-body>
                </fo:table>
             </fo:block>
          </fo:flow>
       </fo:page-sequence>
    </fo:root>
    

    which renders as a table, you will need to add attributes to have borders.

    To insert that approach into your existing stylesheet, you will to take the input namespace into account and prefix the match expressions or select expressions as you have done in the other parts of the stylesheet and then you only need to insert the last two templates into your stylesheet and make sure that you use <xsl:apply-templates/> or <xsl:apply-templates select="values"/> (again, with any needed namespace prefix) at the place where you want to insert the table in the context of the parent of the values element.