3
votes

I have a one row and one of the columns has a list of data. Say I have a row, the 3rd column has 0 or more rows. <xsl:for-each select="./parts"> and for some reason the code I have doesn't seem to work. I am not sure how to implement it. I am getting this error.

org.apache.fop.events.LoggingEventListener processEvent The following feature isn't implemented by Apache FOP, yet: table-layout="auto" (on fo:table) (No context info available) [4/1/13 19:14:38:002 CDT] 00000053 SystemErr R org.apache.fop.fo.ValidationException: "fo:table-cell" is missing child elements. Required content model: marker* (%block;)+ (No context info available)

I have this code and this doesn't work.

<xsl:for-each select="./List">
  <fo:table-row>
    <fo:table-cell border="solid 1px" text-align="center">
      <fo:block font-size="8pt"><xsl:value-of select="group" /></fo:block>
    <fo:table-cell>
  <fo:table-cell border="solid 1px" text-align="left">
    <xsl:for-each select="./parts">
      <fo:block font-size="8pt"><xsl:value-of select="partNumber" /><fo:leader />
      </fo:block>
    </xsl:for-each>
  </fo:table-cell>
 </fo:table-row>
</xsl:for-each>
4
post also your xml please to test your xslt on itMikroDel

4 Answers

3
votes

Try removing strict validations:

fopFactory.setStrictValidation(false);

3
votes

Ok, so the problem your getting is coming from this block.

<fo:table-cell border="solid 1px" text-align="left">
    <xsl:for-each select="./parts">
      <fo:block font-size="8pt"><xsl:value-of select="partNumber" /><fo:leader />
      </fo:block>
    </xsl:for-each>
  </fo:table-cell>

As I believe others have already pointed out, if you have 0 parts elements, then your table cell has no block child. The way I see it, there are two easy fixes. First, try wrapping your for-each statement in another block element like so.

<fo:table-cell border="solid 1px" text-align="left">
<fo:block>
    <xsl:for-each select="./parts">
      <fo:block font-size="8pt"><xsl:value-of select="partNumber" /><fo:leader />
      </fo:block>
    </xsl:for-each>
<fo:block>
  </fo:table-cell>

If you find it has unwanted effects on your formatting, you can play around with the padding and other properties so that the added block still preserves your alignment. This will fix your issue for sure. A slightly more complex alternative would be to use an xsl:choose statement that tests to see if there is at least one part before trying to iterate over them, otherwise it inserts an empty block.

<fo:table-cell border="solid 1px" text-align="left">
<xsl:choose>
<xsl:when test="count(./parts) &gt; 0">
    <xsl:for-each select="./parts">
      <fo:block font-size="8pt"><xsl:value-of select="partNumber" /><fo:leader />
      </fo:block>
    </xsl:for-each>
</xsl:when>
<xsl:otherwise>
<fo:block>&#160;</fo:block>
</xsl:otherwise>
</xsl:choose>
  </fo:table-cell>

Although this is longer, it is also more extensible, for example, if at a future point you wanted it to display the list of parts if there is data, and if not display another value (which also may or may not be present), you can simply add another when block to mitigate that change in the logic.

One last note, the block that I put in the otherwise statement contains  , which is just an encoding for a single white space. If you want your 'empty' block to still reserve a line of space (ie stop it from collapsing if there is no text content) you can use the white space to keep the block from collapsing, otherwise, if you don't care about it collapsing or not, just remove the white space.

1
votes

It seems sometimes your code:

<xsl:for-each select="./parts">
   <fo:block font-size="8pt"><xsl:value-of select="partNumber" /><fo:leader />
    </fo:block>
 </xsl:for-each>

does not return anything. You need to put it into a variable and check it. If there is no value put empty to avoid this error.

1
votes

If you look in the W3 XSL-FO spec for fo:table-cell you will see

Contents:

(%block;)+

The + means "one or more", i.e. obligatory

and the %block entity is defined as follows by W3

The parameter entity, "%block;" in the content models below, contains the following formatting objects:

     block
     block-container
     table-and-caption
     table
     list-block

So Navin Rawat is right, you need to ensure that something is inside your cell.

/ Colm