I am relatively new to XSLT, but I have a problem which seems very strange to me and I hope you will be able to help me out.

I have an xml file which contains information about the x and y sizes of sheets in a document and x and y size of the bitmap projected on that sheet.

<apv>
  <sheet>
    ...
    <attr name="Sheet size x">2159</attr>
    <attr name="Sheet size y">2794</attr>
    <attr name="Front bitmap x size">6624</attr>
    <attr name="Front bitmap y size">5100</attr>
    <attr name="Rear bitmap x size">6624</attr>
    <attr name="Rear bitmap y size">5100</attr>
     ...
  </sheet>
</apv>

Now I want to transform this XML into a PDF file which contains svg images which give a view of the sheets and the bitmap of the sheets. I use fop 0.95 in a Java application to construct the PDF file from the given XML and XSL files.

The important part of my XSL file looks like this (I already stepped into apv/sheet):

<!-- Sheet Variables -->  
<xsl:variable name="sheet_width">
  <xsl:for-each select="attr">
    <xsl:if test="@name = 'Sheet size x'">
      <xsl:value-of select="."/>
    </xsl:if>
  </xsl:for-each>
</xsl:variable>

<xsl:variable name="sheet_height">
  <xsl:for-each select="attr">
    <xsl:if test="@name = 'Sheet size y'">
      <xsl:value-of select="."/>
    </xsl:if>
  </xsl:for-each>
</xsl:variable>

<xsl:variable name="proportion" select="$sheet_width div $sheet_height"/>

<xsl:variable name="svg_height">
  350
</xsl:variable>  

<xsl:variable name="svg_width" select="$proportion * $svg_height"/>

<!-- Front Bitmap Variables -->
<xsl:variable name="front_bitmap_width">
  <xsl:for-each select="attr">
    <xsl:if test="@name = 'Front bitmap y size'">
      <xsl:value-of select="(. div $horizontal_dpi) * 254"/>
    </xsl:if>
  </xsl:for-each>  
</xsl:variable>
      
<xsl:variable name="front_bitmap_height">
  <xsl:for-each select="attr">
    <xsl:if test="@name = 'Front bitmap x size'">
      <xsl:value-of select="(. div $vertical_dpi) * 254"/>
    </xsl:if>
  </xsl:for-each>
</xsl:variable>

<xsl:variable name="svg_front_bitmap_width" select="($front_bitmap_width div $sheet_width) * $svg_width"/>

<xsl:variable name="svg_front_bitmap_height">
  <xsl:choose>
    <xsl:when test="$front_bitmap_height &gt; $sheet_height">
      <xsl:value-of select="$svg_height"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="($front_bitmap_height div $sheet_height) * $svg_height"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<!-- Rear Bitmap Variables -->
<xsl:variable name="rear_bitmap_width">
  <xsl:for-each select="attr">
    <xsl:if test="@name = 'Rear bitmap y size'">
      <xsl:value-of select="(. div $horizontal_dpi) * 254"/>
    </xsl:if>
  </xsl:for-each>
</xsl:variable>

<xsl:variable name="rear_bitmap_height">
  <xsl:for-each select="attr">
    <xsl:if test="@name = 'Rear bitmap x size'">
      <xsl:value-of select="(. div $vertical_dpi) * 254"/>
    </xsl:if>
  </xsl:for-each>
</xsl:variable>

<xsl:variable name="svg_rear_bitmap_width" select="($rear_bitmap_width div $sheet_width) * $svg_width"/>

<xsl:variable name="svg_rear_bitmap_height">
  <xsl:choose>
    <xsl:when test="$rear_bitmap_height &gt; $sheet_height">
      <xsl:value-of select="$svg_height"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="($rear_bitmap_height div $sheet_height) * $svg_height"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>
    ...
<fo:instream-foreign-object>
   <svg:svg width="{$svg_width}" height="{$svg_height}">
     <!-- Draw Rectangle of Sheet -->
     <svg:rect width="{$svg_width}" height="{$svg_height}" style="fill:none; stroke-width:3; stroke:rgb(0,0,0)"/>
     <!-- Draw Rectangle of Front Bitmap -->
     <svg:rect width="{$svg_front_bitmap_width}" height="{$svg_front_bitmap_height}" style="fill:none; stroke-width:2; stroke:rgb(255,0,0)"/>
   </svg:svg>
</fo:instream-foreign-object>
   ...
<fo:instream-foreign-object>
  <svg:svg width="{$svg_width}" height="{$svg_height}" xmlns:xlink="http://www.w3.org/1999/xlink">
    <!-- Draw Rectangle of Sheet -->
    <svg:rect width="{$svg_width}" height="{$svg_height}" style="fill:none; stroke-width:3; stroke:rgb(0,0,0)"/>
    <!-- Draw Rectangle of Rear Bitmap -->
    <svg:rect width="{$svg_rear_bitmap_width}" height="{$svg_rear_bitmap_height}" style="fill:none; stroke-width:2; stroke:rgb(255,0,0)"/>
  </svg:svg>
</fo:instream-foreign-object>
      ...

Now my problem:
When I run the program with this XSL file I get the following error:

SEVERE: svg graphic could not be built: file:/G:/NetBeansProjects/apv2pdf:-1
The attribute "height" of the element <rect> is invalid
org.apache.batik.bridge.BridgeException: file:/G:/NetBeansProjects/apv2pdf:-1
The attribute "height" of the element <rect> is invalid
        at org.apache.batik.bridge.SVGRectElementBridge.buildShape(Unknown Source)
...

The odd thing is that the program worked fine when I only had the front side of the sheet in the XSL file. Now when I replace the $svg_rear_bitmap_width and $svg_rear_bitmap_height (which both have a similar error) with the similar variables for the front it works fine. Also when I replace the variables with a fixed value it works fine. So I suspected the error is in the variables.

After that I tried replacing the variables with a fixed value and the program works fine.
I studied the code for some hours now but I can't really find a difference why everything for the front side of the sheet sheet is fine but doesn't for the rear side. Or I did something wrong completely but somehow works for the front side, then I like to know what the correct way to solve my problem is. Or there is something in the rear side variables wrong that I don't see anymore.

I hope you can help.

Thanks in advance,

Miepmuts

This time I will place my complete code:

<?xml version="1.0" encoding="ISO-8859-1"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">

    <xsl:variable name="horizontal_dpi" select="600"/>
    <xsl:variable name="vertical_dpi" select="600"/>  
      
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">

    <fo:layout-master-set>
      <fo:simple-page-master master-name="A4"
       page-width="210mm" page-height="297mm"
       margin-top="1cm" margin-bottom="1cm"
       margin-left="1cm" margin-right="1cm">
        <fo:region-body/>
      </fo:simple-page-master>
    </fo:layout-master-set>

    <!-- First Page: Textual Representation -->    
      
    <xsl:for-each select="apv/job/sheet">
    <fo:page-sequence master-reference="A4">
      <fo:flow flow-name="xsl-region-body">
        <fo:block>
          <fo:table border-color="black" border-width="1" border-style="solid">
          <fo:table-column column-width="75mm"/>
          <fo:table-column column-width="75mm"/>

          <fo:table-header>
            <fo:table-row>
	      <fo:table-cell border-color="black" border-width="1" border-style="solid">
	        <fo:block font-weight="bold">Attribute</fo:block>
	      </fo:table-cell>
	      <fo:table-cell border-color="black" border-width="1" border-style="solid">
	        <fo:block font-weight="bold">Value</fo:block>
	      </fo:table-cell>
	    </fo:table-row>
      </fo:table-header>

          <fo:table-body>
	    <xsl:for-each select="attr">
	    <fo:table-row>
	    <fo:table-cell border-color="black" border-width="1" border-style="solid">
	      <fo:block><xsl:value-of select="@name"/></fo:block>
	    </fo:table-cell>
	    <fo:table-cell border-color="black" border-width="1" border-style="solid">
	      <fo:block><xsl:value-of select="."/></fo:block>
	    </fo:table-cell>
	    </fo:table-row>
	    </xsl:for-each>
          </fo:table-body>
    	
          </fo:table>
        </fo:block>
      </fo:flow>
    </fo:page-sequence>
    
    <!-- Sheet Variables -->  
      
    <xsl:variable name="sheet_width">
      <xsl:for-each select="attr">
      <xsl:if test="@name = 'Sheet size x'">
        <xsl:value-of select="."/>
      </xsl:if>
      </xsl:for-each>
    </xsl:variable>

    <xsl:variable name="sheet_height">
      <xsl:for-each select="attr">
      <xsl:if test="@name = 'Sheet size y'">
        <xsl:value-of select="."/>
      </xsl:if>
      </xsl:for-each>
    </xsl:variable>

    <xsl:variable name="proportion" select="$sheet_width div $sheet_height"/>

    <xsl:variable name="svg_height">
      350
    </xsl:variable>  

    <xsl:variable name="svg_width" select="$proportion * $svg_height"/>

    <!-- Front Bitmap Variables -->
      
    <xsl:variable name="front_bitmap_width">
      <xsl:for-each select="attr">
        <xsl:if test="@name = 'Front bitmap y size'">
          <xsl:value-of select="(. div $horizontal_dpi) * 254"/>
        </xsl:if>
      </xsl:for-each>  
    </xsl:variable>
      
    <xsl:variable name="front_bitmap_height">
      <xsl:for-each select="attr">
        <xsl:if test="@name = 'Front bitmap x size'">
          <xsl:value-of select="(. div $vertical_dpi) * 254"/>
        </xsl:if>
      </xsl:for-each>
    </xsl:variable>

    <xsl:variable name="svg_front_bitmap_width" select="($front_bitmap_width div $sheet_width) * $svg_width"/>

    <xsl:variable name="svg_front_bitmap_height">
      <xsl:choose>
        <xsl:when test="$front_bitmap_height &gt; $sheet_height">
          <xsl:value-of select="$svg_height"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="($front_bitmap_height div $sheet_height) * $svg_height"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <!-- Rear Bitmap Variables -->

    <xsl:variable name="rear_bitmap_width">
      <xsl:for-each select="attr">
        <xsl:if test="@name = 'Rear bitmap y size'">
          <xsl:value-of select="(. div $horizontal_dpi) * 254"/>
        </xsl:if>
      </xsl:for-each>
    </xsl:variable>

    <xsl:variable name="rear_bitmap_height">
      <xsl:for-each select="attr">
        <xsl:if test="@name = 'Rear bitmap x size'">
          <xsl:value-of select="(. div $vertical_dpi) * 254"/>
        </xsl:if>
      </xsl:for-each>
    </xsl:variable>

    <xsl:variable name="svg_rear_bitmap_width" select="($rear_bitmap_width div $sheet_width) * $svg_width"/>

    <xsl:variable name="svg_rear_bitmap_height">
      <xsl:choose>
        <xsl:when test="$rear_bitmap_height &gt; $sheet_height">
          <xsl:value-of select="$svg_height"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="($rear_bitmap_height div $sheet_height) * $svg_height"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <!-- Second Page: Visual Representation -->  
      
    <fo:page-sequence master-reference="A4">
      <fo:flow flow-name="xsl-region-body">
        <fo:block text-align="center">
          <fo:block>
            Front Sheet
          </fo:block>
          <!-- Front Sheet SVG -->
          <fo:instream-foreign-object>
            <svg:svg width="{$svg_width}" height="{$svg_height}" xmlns:xlink="http://www.w3.org/1999/xlink">
              <svg:defs>
                <svg:path id="sheet_width_path"  d="M15 10 L100 10Z"/>
                <svg:path id="sheet_height_path" d="M5 10 L5 100Z"/>
                <svg:path id="bitmap_width_path" d="M{$svg_front_bitmap_width} 10 L0 10Z"/>
                <svg:path id="bitmap_height_path" d="M5 {$svg_front_bitmap_height} L5 0Z"/>
              </svg:defs>
              <svg:text>
                <svg:textPath xlink:href="#sheet_width_path">
                  <xsl:value-of select="$sheet_width"/>
                </svg:textPath>
                <svg:textPath xlink:href="#sheet_height_path">
                  <xsl:value-of select="$sheet_height"/>
                </svg:textPath>
              </svg:text>
              <svg:text fill="red">
                <svg:textPath xlink:href="#bitmap_width_path">
                  <xsl:value-of select="$front_bitmap_width"/>
                </svg:textPath>
                <svg:textPath xlink:href="#bitmap_height_path">
                  <xsl:value-of select="$front_bitmap_height"/>
                </svg:textPath>
              </svg:text>
              <!-- Draw Rectangle of Sheet -->
              <svg:rect width="{$svg_width}" height="{$svg_height}" style="fill:none; stroke-width:3; stroke:rgb(0,0,0)"/>
              <!-- Draw Rectangle of Front Bitmap -->
              <svg:rect width="{$svg_front_bitmap_width}" height="{$svg_front_bitmap_height}" style="fill:none; stroke-width:2; stroke:rgb(255,0,0)"/>
            </svg:svg>
          </fo:instream-foreign-object>
        </fo:block>
        <fo:block text-align="center">
          <fo:block>
            Rear Sheet
          </fo:block>
          <!-- Rear Sheet SVG -->
          <fo:instream-foreign-object>
            <svg:svg width="{$svg_width}" height="{$svg_height}" xmlns:xlink="http://www.w3.org/1999/xlink">
              <svg:defs>
                <svg:path id="sheet_width_path"  d="M15 10 L100 10Z"/>
                <svg:path id="sheet_height_path" d="M5 10 L5 100Z"/>
              </svg:defs>
              <svg:text>
                <svg:textPath xlink:href="#sheet_width_path">
                  <xsl:value-of select="$sheet_width"/>
                </svg:textPath>
                <svg:textPath xlink:href="#sheet_height_path">
                  <xsl:value-of select="$sheet_height"/>
                </svg:textPath>
              </svg:text>
              <!-- Draw Rectangle of Sheet -->
              <svg:rect width="{$svg_width}" height="{$svg_height}" style="fill:none; stroke-width:3; stroke:rgb(0,0,0)"/>
              <!-- Draw Rectangle of Rear Bitmap -->
              <svg:rect width="{$svg_rear_bitmap_width}" height="{$svg_rear_bitmap_height}" style="fill:none; stroke-width:2; stroke:rgb(255,0,0)"/>    
            </svg:svg>
          </fo:instream-foreign-object>
        </fo:block>
      </fo:flow>
    </fo:page-sequence>

    </xsl:for-each>

    </fo:root>

  </xsl:template>
</xsl:stylesheet>

This is how I think the code should work, but it doesn't because it generates the error:

SEVERE: svg graphic could not be built: file:/G:/NetBeansProjects/apv2pdf:-1
The attribute "width" of the element <rect> is invalid
org.apache.batik.bridge.BridgeException: file:/G:/NetBeansProjects/apv2pdf:-1
The attribute "width" of the element <rect> is invalid
        at org.apache.batik.bridge.SVGRectElementBridge.buildShape(Unknown Source)
...

After some thought I decided to try to isolate the problem some more.

I output the values of both rear and front side svg_bitmap_width and svg_bitmap_height to the screen and there is nothing special to see, for the same input it even comes up with the same numbers.

Next I tried to see where is something wrong.
I set the width and height of the rear bitmap rectangle to a fixed value, and for the width I worked all the way up in the variables replacing the fixed value with the corresponding variable. So I replaced width in the rect with the correct value, but I replaced svg_rear_bitmap_width with a fixed value. The program works fine that way. When I finally go back to the original value of svg_rear_bitmap_width and replace the assignment in the value of rear_bitmap_width to a fixed value it goes well. I walked and found a similar solution for the height.

The conclusion is that for fixed values for rear_bitmap_width and height everyting goes well, but when I do some calculation there the program crashes, while the calculation is the same as for the front bitmap variables for which the program doesn't give any error.

I still don't really see what is worng, but I hope someone will be able to point out my mistake(s).

Due to new developments on the sheet lay-out. I had to move all the rear-sheet information to another page.

That works fine.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.