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 > $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 > $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 > $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 > $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.