Loading ...
Sorry, an error occurred while loading the content.

Re: [XSL-FO] Generating table rows dynamically

Expand Messages
  • G. Ken Holman
    ... This is an XSLT question, not an XSL-FO question. First create the situation where you can package each row, then fill the row from each point that
    Message 1 of 9 , Jul 4, 2003
    • 0 Attachment
      At 2003-07-04 04:34 -0700, Nilendu Bhattacharya wrote:
      >I want to dynamically generate rows depending on the
      >avalability of
      >data. For example for the following XML data....
      >...
      >One the above data I want the table in format below
      >
      >-----------|---------|
      >One | Two |
      >-----------|---------|
      >Three | Four |
      >-----------|---------|
      >Five | |
      >-----------|---------|

      This is an XSLT question, not an XSL-FO question.

      First create the situation where you can package each row, then fill the
      row from each point that triggers a row. A quick structural example is
      below, without using the FO vocabulary ... changing it to FO is left as an
      exercise for the reader. :{)}

      .................. Ken


      t:\ftemp>type nilendu.xml
      <Categories>
      <Category> One </Category>
      <Category> Two </Category>
      <Category> Three </Category>
      <Category> Four </Category>
      <Category> Five </Category>
      </Categories>

      t:\ftemp>type nilendu.xsl
      <?xml version="1.0" encoding="iso-8859-1"?>
      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      version="1.0">

      <xsl:output indent="yes"/>

      <xsl:template match="/Categories">
      <table>
      <xsl:for-each select="Category[position() mod 2 != 0]">
      <row>
      <cell><xsl:value-of select="."/></cell>
      <cell>
      <xsl:value-of select="following-sibling::Category[1]"/>
      </cell>
      </row>
      </xsl:for-each>
      </table>
      </xsl:template>

      </xsl:stylesheet>
      t:\ftemp>saxon nilendu.xml nilendu.xsl
      <?xml version="1.0" encoding="utf-8"?>
      <table>
      <row>
      <cell> One </cell>
      <cell> Two </cell>
      </row>
      <row>
      <cell> Three </cell>
      <cell> Four </cell>
      </row>
      <row>
      <cell> Five </cell>
      <cell/>
      </row>
      </table>
      t:\ftemp>



      --
      Upcoming hands-on courses: in-house corporate training available;
      North America public: XSL-FO Aug 4,2003; XSLT/XPath Aug 12, 2003

      G. Ken Holman mailto:gkholman@...
      Crane Softwrights Ltd. http://www.CraneSoftwrights.com/f/
      Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (F:-0995)
      ISBN 0-13-065196-6 Definitive XSLT and XPath
      ISBN 0-13-140374-5 Definitive XSL-FO
      ISBN 1-894049-08-X Practical Transformation Using XSLT and XPath
      ISBN 1-894049-11-X Practical Formatting Using XSL-FO
      Member of the XML Guild of Practitioners: http://XMLGuild.info
      Male Breast Cancer Awareness http://www.CraneSoftwrights.com/f/bc
    • nilendu_b
      Thanks a lot Ken for the beautiful solution provided by you ... Here is the xslfo.
      Message 2 of 9 , Jul 4, 2003
      • 0 Attachment
        Thanks a lot Ken for the beautiful solution provided by you ... Here
        is the xslfo.

        <?xml version="1.0" encoding="UTF-8"?>
        <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:fo="http://www.w3.org/1999/XSL/Format">
        <xsl:output indent="yes"/>
        <xsl:template match="/Categories">
        <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
        xmlns:fox="http://xml.apache.org/fop/extensions">
        <!-- defines page layout -->
        <fo:layout-master-set>
        <fo:simple-page-master margin-
        right="1cm" margin-left="1cm" margin-bottom="0.5cm" margin-
        top="0.75cm" page-width="11in" page-height="8.5in" master-name="all">
        <fo:region-body margin-
        top="1.5cm" margin-bottom=".5cm"/>
        <fo:region-before
        precedence="true" extent="4cm"/>
        <fo:region-after
        precedence="true" extent="4.5cm"/>
        </fo:simple-page-master>
        <fo:page-sequence-master master-
        name="psmA">
        <fo:repeatable-page-master-
        alternatives>
        <fo:conditional-page-
        master-reference master-reference="all" page-position="first"/>
        <fo:conditional-page-
        master-reference master-reference="all" page-position="rest"/>
        <!-- recommended
        fallback procedure -->
        <fo:conditional-page-
        master-reference master-reference="all"/>
        </fo:repeatable-page-master-
        alternatives>
        </fo:page-sequence-master>
        </fo:layout-master-set>
        <fo:page-sequence master-reference="psmA">
        <fo:flow flow-name="xsl-region-body">
        <fo:block>
        <fo:table
        table-layout="fixed">

        <fo:table-column column-width="12.6cm"/>

        <fo:table-column column-width="12.6cm"/>

        <fo:table-body>


        <xsl:for-each select="Category[position() mod 2 != 0]">

        <fo:table-row>

        <fo:table-cell>

        <fo:block>

        <xsl:value-of
        select="."/>

        </fo:block>

        </fo:table-cell>

        <fo:table-cell>

        <fo:block>

        <xsl:value-of
        select="following-sibling::Category[1]"/>

        </fo:block>

        </fo:table-cell>

        </fo:table-row>


        </xsl:for-each>

        </fo:table-body>
        </fo:table>
        </fo:block>
        </fo:flow>
        </fo:page-sequence>
        </fo:root>
        </xsl:template>
        </xsl:stylesheet>




        -----------
        --- In XSL-FO@yahoogroups.com, "G. Ken Holman" <gkholman@c...> wrote:
        > At 2003-07-04 04:34 -0700, Nilendu Bhattacharya wrote:
        > >I want to dynamically generate rows depending on the
        > >avalability of
        > >data. For example for the following XML data....
        > >...
        > >One the above data I want the table in format below
        > >
        > >-----------|---------|
        > >One | Two |
        > >-----------|---------|
        > >Three | Four |
        > >-----------|---------|
        > >Five | |
        > >-----------|---------|
        >
        > This is an XSLT question, not an XSL-FO question.
        >
        > First create the situation where you can package each row, then
        fill the
        > row from each point that triggers a row. A quick structural
        example is
        > below, without using the FO vocabulary ... changing it to FO is
        left as an
        > exercise for the reader. :{)}
        >
        > .................. Ken
        >
        >
        > t:\ftemp>type nilendu.xml
        > <Categories>
        > <Category> One </Category>
        > <Category> Two </Category>
        > <Category> Three </Category>
        > <Category> Four </Category>
        > <Category> Five </Category>
        > </Categories>
        >
        > t:\ftemp>type nilendu.xsl
        > <?xml version="1.0" encoding="iso-8859-1"?>
        > <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        > version="1.0">
        >
        > <xsl:output indent="yes"/>
        >
        > <xsl:template match="/Categories">
        > <table>
        > <xsl:for-each select="Category[position() mod 2 != 0]">
        > <row>
        > <cell><xsl:value-of select="."/></cell>
        > <cell>
        > <xsl:value-of select="following-sibling::Category[1]"/>
        > </cell>
        > </row>
        > </xsl:for-each>
        > </table>
        > </xsl:template>
        >
        > </xsl:stylesheet>
        > t:\ftemp>saxon nilendu.xml nilendu.xsl
        > <?xml version="1.0" encoding="utf-8"?>
        > <table>
        > <row>
        > <cell> One </cell>
        > <cell> Two </cell>
        > </row>
        > <row>
        > <cell> Three </cell>
        > <cell> Four </cell>
        > </row>
        > <row>
        > <cell> Five </cell>
        > <cell/>
        > </row>
        > </table>
        > t:\ftemp>
        >
        >
        >
        > --
        > Upcoming hands-on courses: in-house corporate training available;
        > North America public: XSL-FO Aug 4,2003; XSLT/XPath Aug 12, 2003
        >
        > G. Ken Holman mailto:gkholman@C...
        > Crane Softwrights Ltd. http://www.CraneSoftwrights.com/f/
        > Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (F:-0995)
        > ISBN 0-13-065196-6 Definitive XSLT and XPath
        > ISBN 0-13-140374-5 Definitive XSL-FO
        > ISBN 1-894049-08-X Practical Transformation Using XSLT and XPath
        > ISBN 1-894049-11-X Practical Formatting Using XSL-FO
        > Member of the XML Guild of Practitioners: http://XMLGuild.info
        > Male Breast Cancer Awareness http://www.CraneSoftwrights.com/f/bc
      • Praveen Sam
        Assuming that each column(cell) is independant of the other ... you can try this ... Look at the snippet below .. Basically what am doing here is inside the
        Message 3 of 9 , Jul 4, 2003
        • 0 Attachment
          Assuming that each column(cell) is independant of the
          other ... you can try this ...

          Look at the snippet below ..

          Basically what am doing here is inside the
          table-cell(column) - am doing a for-each loop - so
          when ever it finds "data" - it inserts a new
          line("&x2028;") - check the correct VALUE - cant
          remember top off my head
          and starts rendering a new row with data .

          Sometimes column1 might have data and corresponding
          column2 might not have and still you want to keep the
          rows together then you might want to use
          white-space-collapse="false" so that you get a blank
          line in column2 and it keeps going ...

          Hope this helps ....

          <fo:table ......>
          ....
          ...
          ...
          <fo:table-body>
          <fo:table-row>
          <fo:table-cell>
          <fo:block text-align="start" font-size="10pt"
          font-family="sans-serif">
          <xsl:for-each select="categories/category1">
          <fo:block>
          <xsl:text>&x2028;</xsl:text> <!-- inserts a newline
          -->
          </fo:block>
          <xsl:apply-templates />
          </xsl:for-each>
          </fo:block>
          </fo:table-cell>
          <fo:table-cell>
          <fo:block text-align="start" font-size="10pt"
          font-family="sans-serif">
          <xsl:for-each select="categories/category2">
          <fo:block>
          <xsl:text>&x2028;</xsl:text> <!-- inserts a newline
          -->
          </fo:block>
          <xsl:apply-templates />
          </xsl:for-each>
          </fo:block>
          </fo:table-cell>
          </fo:table-row>
          </fo:table-body>
          </fo:table>


          --- nilendu_b <nilendu_b@...> wrote:
          > Hi!,
          >
          > I want to dynamically generate rows depending on the
          > avalability of
          > data. For example for the following XML data....
          >
          > <Categories>
          > <Category> One <Category>
          > <Category> Two <Category>
          > <Category> Three <Category>
          > <Category> Four <Category>
          > <Category> Five <Category>
          > </Categories>
          >
          > One the above data I want the table in format below
          >
          > -----------|---------|
          > One | Two |
          > -----------|---------|
          > Three | Four |
          > -----------|---------|
          > Five | |
          > -----------|---------|
          >
          > Can any one help me please.
          >
          > Thanks in advance.
          > Nilendu
          >
          >


          =====


          __________________________________
          Do you Yahoo!?
          SBC Yahoo! DSL - Now only $29.95 per month!
          http://sbc.yahoo.com
        • G. Ken Holman
          I thought of a more elegant approach than I first recommended because of a very useful feature available in XSL-FO than can be taken advantage of in this case.
          Message 4 of 9 , Jul 4, 2003
          • 0 Attachment
            I thought of a more elegant approach than I first recommended because of a
            very useful feature available in XSL-FO than can be taken advantage of in
            this case.

            Following my earlier suggestion, you correctly used the row-oriented
            row-grouping strategy for building rows of an XSL-FO table:

            At 2003-07-04 13:32 +0000, nilendu_b wrote:
            > <xsl:for-each select="Category[position() mod 2 != 0]">
            > <fo:table-row>
            > <fo:table-cell>
            > <fo:block>
            > <xsl:value-of select="."/>
            > </fo:block>
            > </fo:table-cell>
            > <fo:table-cell>
            > <fo:block>
            > <xsl:value-of
            > select="following-sibling::Category[1]"/>
            > </fo:block>
            > </fo:table-cell>
            > </fo:table-row>
            > </xsl:for-each>

            My suggestion now is to use the cell-oriented row-grouping strategy
            available in XSL-FO:

            <fo:page-sequence master-reference="psmA">
            <fo:flow flow-name="xsl-region-body">
            <fo:block>
            <fo:table table-layout="fixed">
            <fo:table-column column-width="12.6cm"/>
            <fo:table-column column-width="12.6cm"/>
            <fo:table-body>
            <xsl:for-each select="Category">
            <fo:table-cell>
            <xsl:if test="position() mod 2">
            <xsl:attribute name="starts-row">
            <xsl:text>true</xsl:text>
            </xsl:attribute>
            </xsl:if>
            <fo:block>
            <xsl:value-of select="."/>
            </fo:block>
            </fo:table-cell>
            </xsl:for-each>
            </fo:table-body>
            </fo:table>
            </fo:block>
            </fo:flow>
            </fo:page-sequence>

            Note how in the above that the <table-cell>s are children of <table-body>
            and that there is no <table-row> construct: I'm using starts-row="true"
            every second entry to tell the processor to start a new row of the table.

            One doesn't have to use the following-sibling axis or try and do grouping
            in logic ... rather, one takes advantage of XSL-FO's implicit grouping
            ability by signalling the need to start (or end) a row with the given
            cell. This makes the XSLT much easier to write and much easier to understand.

            I hope this helps.

            ........................ Ken

            --
            Upcoming hands-on courses: in-house corporate training available;
            North America public: XSL-FO Aug 4,2003; XSLT/XPath Aug 12, 2003

            G. Ken Holman mailto:gkholman@...
            Crane Softwrights Ltd. http://www.CraneSoftwrights.com/f/
            Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (F:-0995)
            ISBN 0-13-065196-6 Definitive XSLT and XPath
            ISBN 0-13-140374-5 Definitive XSL-FO
            ISBN 1-894049-08-X Practical Transformation Using XSLT and XPath
            ISBN 1-894049-11-X Practical Formatting Using XSL-FO
            Member of the XML Guild of Practitioners: http://XMLGuild.info
            Male Breast Cancer Awareness http://www.CraneSoftwrights.com/f/bc
          • Praveen Sam
            This is really a very elegant solution compared to what I suggested. But if I remember correctly this feature was not supported in the earlier versions of
            Message 5 of 9 , Jul 4, 2003
            • 0 Attachment
              This is really a "very" elegant solution compared to
              what I suggested.

              But if I remember correctly this feature was not
              supported in the earlier versions of fop - "0.20.1" -
              it would complain that it was not yet supported so had
              to come up with a work around solution.

              Thanks Ken for the insight.

              --- "G. Ken Holman" <gkholman@...>
              wrote:
              > I thought of a more elegant approach than I first
              > recommended because of a
              > very useful feature available in XSL-FO than can be
              > taken advantage of in
              > this case.
              >
              > Following my earlier suggestion, you correctly used
              > the row-oriented
              > row-grouping strategy for building rows of an XSL-FO
              > table:
              >
              > At 2003-07-04 13:32 +0000, nilendu_b wrote:
              > > <xsl:for-each select="Category[position()
              > mod 2 != 0]">
              > > <fo:table-row>
              > > <fo:table-cell>
              > > <fo:block>
              > >
              > <xsl:value-of select="."/>
              > > </fo:block>
              > > </fo:table-cell>
              > > <fo:table-cell>
              > > <fo:block>
              > >
              > <xsl:value-of
              > > select="following-sibling::Category[1]"/>
              > > </fo:block>
              > > </fo:table-cell>
              > > </fo:table-row>
              > > </xsl:for-each>
              >
              > My suggestion now is to use the cell-oriented
              > row-grouping strategy
              > available in XSL-FO:
              >
              > <fo:page-sequence master-reference="psmA">
              > <fo:flow flow-name="xsl-region-body">
              > <fo:block>
              > <fo:table table-layout="fixed">
              > <fo:table-column
              > column-width="12.6cm"/>
              > <fo:table-column
              > column-width="12.6cm"/>
              > <fo:table-body>
              > <xsl:for-each
              > select="Category">
              > <fo:table-cell>
              > <xsl:if
              > test="position() mod 2">
              > <xsl:attribute
              > name="starts-row">
              >
              > <xsl:text>true</xsl:text>
              > </xsl:attribute>
              > </xsl:if>
              > <fo:block>
              > <xsl:value-of
              > select="."/>
              > </fo:block>
              > </fo:table-cell>
              > </xsl:for-each>
              > </fo:table-body>
              > </fo:table>
              > </fo:block>
              > </fo:flow>
              > </fo:page-sequence>
              >
              > Note how in the above that the <table-cell>s are
              > children of <table-body>
              > and that there is no <table-row> construct: I'm
              > using starts-row="true"
              > every second entry to tell the processor to start a
              > new row of the table.
              >
              > One doesn't have to use the following-sibling axis
              > or try and do grouping
              > in logic ... rather, one takes advantage of XSL-FO's
              > implicit grouping
              > ability by signalling the need to start (or end) a
              > row with the given
              > cell. This makes the XSLT much easier to write and
              > much easier to understand.
              >
              > I hope this helps.
              >
              > ........................ Ken
              >
              > --
              > Upcoming hands-on courses: in-house corporate
              > training available;
              > North America public: XSL-FO Aug 4,2003; XSLT/XPath
              > Aug 12, 2003
              >
              > G. Ken Holman
              > mailto:gkholman@...
              > Crane Softwrights Ltd.
              > http://www.CraneSoftwrights.com/f/
              > Box 266, Kars, Ontario CANADA K0A-2E0
              > +1(613)489-0999 (F:-0995)
              > ISBN 0-13-065196-6 Definitive
              > XSLT and XPath
              > ISBN 0-13-140374-5
              > Definitive XSL-FO
              > ISBN 1-894049-08-X Practical Transformation Using
              > XSLT and XPath
              > ISBN 1-894049-11-X Practical Formatting
              > Using XSL-FO
              > Member of the XML Guild of Practitioners:
              > http://XMLGuild.info
              > Male Breast Cancer Awareness
              > http://www.CraneSoftwrights.com/f/bc
              >
              >


              =====


              __________________________________
              Do you Yahoo!?
              SBC Yahoo! DSL - Now only $29.95 per month!
              http://sbc.yahoo.com
            • nilendu_b
              I think it is excellent solution but i ran into following problems... When I used fop 0.20.4 it said starts-row not supported yet . Then I tried with fop
              Message 6 of 9 , Jul 5, 2003
              • 0 Attachment
                I think it is excellent solution but i ran into following problems...

                When I used fop 0.20.4 it said "starts-row not supported yet".
                Then I tried with fop 0.20.5 and then it said "A table cell must be a
                child of fo:table-row, not fo:table-body"

                Nilendu

                --- In XSL-FO@yahoogroups.com, "G. Ken Holman" <gkholman@c...> wrote:
                > I thought of a more elegant approach than I first recommended
                because of a
                > very useful feature available in XSL-FO than can be taken advantage
                of in
                > this case.
                >
                > Following my earlier suggestion, you correctly used the row-
                oriented
                > row-grouping strategy for building rows of an XSL-FO table:
                >
                > At 2003-07-04 13:32 +0000, nilendu_b wrote:
                > > <xsl:for-each select="Category[position() mod 2 != 0]">
                > > <fo:table-row>
                > > <fo:table-cell>
                > > <fo:block>
                > > <xsl:value-of select="."/>
                > > </fo:block>
                > > </fo:table-cell>
                > > <fo:table-cell>
                > > <fo:block>
                > > <xsl:value-of
                > > select="following-sibling::Category[1]"/>
                > > </fo:block>
                > > </fo:table-cell>
                > > </fo:table-row>
                > > </xsl:for-each>
                >
                > My suggestion now is to use the cell-oriented row-grouping strategy
                > available in XSL-FO:
                >
                > <fo:page-sequence master-reference="psmA">
                > <fo:flow flow-name="xsl-region-body">
                > <fo:block>
                > <fo:table table-layout="fixed">
                > <fo:table-column column-width="12.6cm"/>
                > <fo:table-column column-width="12.6cm"/>
                > <fo:table-body>
                > <xsl:for-each select="Category">
                > <fo:table-cell>
                > <xsl:if test="position() mod 2">
                > <xsl:attribute name="starts-row">
                > <xsl:text>true</xsl:text>
                > </xsl:attribute>
                > </xsl:if>
                > <fo:block>
                > <xsl:value-of select="."/>
                > </fo:block>
                > </fo:table-cell>
                > </xsl:for-each>
                > </fo:table-body>
                > </fo:table>
                > </fo:block>
                > </fo:flow>
                > </fo:page-sequence>
                >
                > Note how in the above that the <table-cell>s are children of <table-
                body>
                > and that there is no <table-row> construct: I'm using starts-
                row="true"
                > every second entry to tell the processor to start a new row of the
                table.
                >
                > One doesn't have to use the following-sibling axis or try and do
                grouping
                > in logic ... rather, one takes advantage of XSL-FO's implicit
                grouping
                > ability by signalling the need to start (or end) a row with the
                given
                > cell. This makes the XSLT much easier to write and much easier to
                understand.
                >
                > I hope this helps.
                >
                > ........................ Ken
                >
                > --
                > Upcoming hands-on courses: in-house corporate training available;
                > North America public: XSL-FO Aug 4,2003; XSLT/XPath Aug 12, 2003
                >
                > G. Ken Holman mailto:gkholman@C...
                > Crane Softwrights Ltd. http://www.CraneSoftwrights.com/f/
                > Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (F:-0995)
                > ISBN 0-13-065196-6 Definitive XSLT and XPath
                > ISBN 0-13-140374-5 Definitive XSL-FO
                > ISBN 1-894049-08-X Practical Transformation Using XSLT and XPath
                > ISBN 1-894049-11-X Practical Formatting Using XSL-FO
                > Member of the XML Guild of Practitioners: http://XMLGuild.info
                > Male Breast Cancer Awareness http://www.CraneSoftwrights.com/f/bc
              • G. Ken Holman
                ... That tells me FOP isn t yet supporting the formatting object correctly. The Recommendation does allow children of in order to
                Message 7 of 9 , Jul 5, 2003
                • 0 Attachment
                  At 2003-07-05 09:15 +0000, nilendu_b wrote:
                  >I think it is excellent solution but i ran into following problems...
                  >
                  >When I used fop 0.20.4 it said "starts-row not supported yet".
                  >Then I tried with fop 0.20.5 and then it said "A table cell must be a
                  >child of fo:table-row, not fo:table-body"

                  That tells me FOP isn't yet supporting the formatting object
                  correctly. The Recommendation does allow <table-cell> children of
                  <table-body> in order to use the cell-based row-grouping strategy with
                  starts-row= and ends-row= properties. Using the <table-row> for the
                  row-based row-grouping strategy is only one of the two options and is not
                  mandatory.

                  Both Antenna House and RenderX support it, and I teach and use this in the
                  exercises of my training course.

                  ............... Ken


                  --
                  Upcoming hands-on courses: in-house corporate training available;
                  North America public: XSL-FO Aug 4,2003; XSLT/XPath Aug 12, 2003

                  G. Ken Holman mailto:gkholman@...
                  Crane Softwrights Ltd. http://www.CraneSoftwrights.com/f/
                  Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (F:-0995)
                  ISBN 0-13-065196-6 Definitive XSLT and XPath
                  ISBN 0-13-140374-5 Definitive XSL-FO
                  ISBN 1-894049-08-X Practical Transformation Using XSLT and XPath
                  ISBN 1-894049-11-X Practical Formatting Using XSL-FO
                  Member of the XML Guild of Practitioners: http://XMLGuild.info
                  Male Breast Cancer Awareness http://www.CraneSoftwrights.com/f/bc
                Your message has been successfully submitted and would be delivered to recipients shortly.