Toon posts:

XML & XSL omzetten naar pdf met FOP

Pagina: 1
Acties:
  • 250 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Ik wil met FOP van een xml file (en bijbehorend xsl file) een pdf file maken. Echter ik krijg dan elke keer een foutmelding:

[INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser
[ERROR] javax.xml.transform.TransformerConfigurationException: javax.xml.transform.TransformerException: javax.xml.transform.TransformersException: stylesheet requires attribute: version


Ik roep fop als volgt aan (In Win95):
fop -xsl wafels.xsl -xml wafels.xml -pdf wafels.pdf

Het luk me wel om een fo file naar pdf om te zetten.


De xml file (voorbeeld van internet geplukt):

<?xml version="1.0"?>
<breakfast_menu>
<food>
<name>Belgian Waffles</name>
<price>$5.95</price>
<description>two of our famous Belgian Waffles with plenty of real maple syrup</description>
<calories>650</calories>
</food>
<food>
<name>Strawberry Belgian Waffles</name>
<price>$7.95</price>
<description>light Belgian waffles covered with strawberries and whipped cream</description>
<calories>900</calories>
</food>
<food>
<name>Berry-Berry Belgian Waffles</name>
<price>$8.95</price>
<description>light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
<calories>900</calories>
</food>
<food>
<name>French Toast</name>
<price>$4.50</price>
<description>thick slices made from our homemade sourdough bread</description>
<calories>600</calories>
</food>
<food>
<name>Homestyle Breakfast</name>
<price>$6.95</price>
<description>two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>
<calories>950</calories>
</food>
</breakfast_menu>


De xsl file:

<?xml version="1.0"?>
<HTML xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<BODY STYLE="font-family:Arial, helvetica, sans-serif; font-size:12pt;
background-color:#EEEEEE">
<xsl:for-each select="breakfast_menu/food">
<DIV STYLE="background-color:teal; color:white; padding:4px">
<SPAN STYLE="font-weight:bold; color:white"><xsl:value-of select="name"/></SPAN>
- <xsl:value-of select="price"/>
</DIV>
<DIV STYLE="margin-left:20px; margin-bottom:1em; font-size:10pt">
<xsl:value-of select="description"/>
<SPAN STYLE="font-style:italic">
(<xsl:value-of select="calories"/> calories per serving)
</SPAN>
</DIV>
</xsl:for-each>
</BODY>
</HTML>


Weet iemand wat het probleem is?

  • whoami
  • Registratie: December 2000
  • Laatst online: 16:37
Ja, er is blijkbaar iets mis met uw stylesheet.

google results

https://fgheysels.github.io/


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Je gebruikt Working Draft XSLT: dit kan je zien aan de namespace en opzet van je transformatie. Waarschijnlijk heb je eerder in Internet Explorer gewerkt of gebruik je een achterhaalde bron.

Je moet overstappen op de XSLT Recommendation (en dus documentatie gebruiken die daarop gebaseerd is).

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Bovendien: FOP heet niet voor niets FOP. Als je een XML document om wilt zetten naar PDF met behulp van XSLT en FOP moet je het transformeren naar XSL Formatting Objects. Dit is iets heel anders dan XHTML!

Om je een indruk te geven hier een (vrijwel) volledige XSL Transformatie die iets transformeert naar FO. Als je hier helemaal geen bal van snapt, zou ik me eerst eens goed in FO verdiepen ;) .

(sorry voor de layout verneuking)
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<xsl:transform
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
     xmlns:fo="http://www.w3.org/1999/XSL/Format">
 
  <xsl:attribute-set name="text-cell">
    <xsl:attribute name="start-indent">0pt</xsl:attribute>
    <xsl:attribute name="text-align">start</xsl:attribute>
    <xsl:attribute name="padding-left">3pt</xsl:attribute>
    <xsl:attribute name="padding-top">3pt</xsl:attribute>
    <xsl:attribute name="padding-bottom">3pt</xsl:attribute>
    <xsl:attribute name="padding-right">3pt</xsl:attribute>
    <xsl:attribute name="border-width">0.5pt</xsl:attribute>
    <xsl:attribute name="border-style">solid</xsl:attribute>
  </xsl:attribute-set>
 
  <xsl:template match="reservations">
    <fo:root>
      <fo:layout-master-set>
        <fo:simple-page-master 
                  margin-right="1cm"
                   margin-left="1cm"
                 margin-bottom="1cm"
                    margin-top="1cm"
                    page-width="21cm"
                   page-height="29.7cm"
                   master-name="first">
          <fo:region-before extent="1cm"/>
          <fo:region-body margin-top="1cm" margin-bottom="1.5cm"/>
          <fo:region-after extent="1cm"/>
        </fo:simple-page-master>
      </fo:layout-master-set>
   
      <fo:page-sequence master-reference="first">
  
        <fo:static-content flow-name="xsl-region-before">
          <fo:block line-height="14pt" font-size="10pt" text-align="start">Reserveringen - afgedrukt
            <xsl:apply-templates select="date:create()"/>
          </fo:block>
        </fo:static-content>
      
        <fo:static-content flow-name="xsl-region-after">
          <fo:block line-height="14pt" font-size="10pt" text-align="end">Pagina <fo:page-number/></fo:block>
        </fo:static-content>
      
        <fo:flow flow-name="xsl-region-body">
          <fo:table font-size="10pt">
            <fo:table-column column-width="3.5cm"/>
            <fo:table-column column-width="4cm"/>
            <fo:table-column column-width="3.2cm"/>
            <fo:table-column column-width="3.2cm"/>
            <fo:table-column column-width="5cm"/>
  
            <fo:table-header border-bottom-width="0pt" border-width="1.5pt" border-style="solid" font-weight="bold">
              <fo:table-row>
                <fo:table-cell xsl:use-attribute-sets="text-cell">
                  <fo:block>Item</fo:block>
                </fo:table-cell>
                <fo:table-cell xsl:use-attribute-sets="text-cell">
                  <fo:block>Klant</fo:block>
                </fo:table-cell>
                <fo:table-cell xsl:use-attribute-sets="text-cell">
                  <fo:block>Starttijd</fo:block>
                </fo:table-cell>
                <fo:table-cell xsl:use-attribute-sets="text-cell">
                  <fo:block>Eindtijd</fo:block>
                </fo:table-cell>
                <fo:table-cell xsl:use-attribute-sets="text-cell">
                  <fo:block>Opmerking</fo:block>
                </fo:table-cell>
              </fo:table-row>
            </fo:table-header>
        
            <fo:table-body border-width="1.5pt" border-style="solid">
              <xsl:apply-templates select="reservation"/>
            </fo:table-body>
   
            <fo:table-footer/>
  
          </fo:table>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template>
   
  <xsl:template match="reservation">
    <fo:table-row>
      <fo:table-cell xsl:use-attribute-sets="text-cell">
        <fo:block>
          <xsl:apply-templates select="product/description"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell xsl:use-attribute-sets="text-cell">
        <fo:block>
          <xsl:apply-templates select="customer/name"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell xsl:use-attribute-sets="text-cell">
        <fo:block>
          <xsl:apply-templates select="start/date-time"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell xsl:use-attribute-sets="text-cell">
        <fo:block>
          <xsl:apply-templates select="end/date-time"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell xsl:use-attribute-sets="text-cell">
        <fo:block>
          <xsl:apply-templates select="remark"/>
        </fo:block>
      </fo:table-cell>
    </fo:table-row>
  </xsl:template>
  
  <xsl:template match="date-time">
    <xsl:apply-templates select="day-of-month"/>
    <xsl:text>-</xsl:text>
    <xsl:apply-templates select="month"/>
    <xsl:text>-</xsl:text>
    <xsl:apply-templates select="year"/>
    <xsl:text> </xsl:text>
    <xsl:apply-templates select="hour-of-day"/>
    <xsl:text>:</xsl:text>
    <xsl:apply-templates select="minute"/>
  </xsl:template>
  
  <xsl:template match="day-of-month | month | hour-of-day | minute">
    <xsl:value-of select="format-number(number(text()), '00')"/>
  </xsl:template>
  
</xsl:transform>

[ Voor 19% gewijzigd door mbravenboer op 30-01-2003 12:58 ]

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

Topicstarter
Bedankt voor de snelle reaktie. Ik zal eerst eens in de materie duiken.

Verwijderd

Topicstarter
Als ik het goed heb begrepen heb je dus:
1) XML + XSLT Recommendation
2) XSL:FO (bevat dus data + opmaak in 1 bestand)

Als ik voor optie 1 kies dan krijg je dus dit:
fop -xsl test.xsl -xml test.xml -pdf test.pdf
En anders:
fop -fo test.fo -pdf test.pdf

In mijn geval wordt de XML code gegeneerd door een programma. Met een editor (XMLSpy ?) moet een bijbehorend XSL bestand gemaakt worden.

Vervolgens met FOP omzetten naar pdf of PostScript.

Is mijn bovenstaande redenatie correct of niet? Als dit niet zo is dan snap ik niet waarom FOP de optie: "fop -xsl test.xsl -xml test.xml -pdf test.pdf" heeft.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
vandenfire: Als ik het goed heb begrepen heb je dus:
1) XML + XSLT Recommendation
2) XSL:FO (bevat dus data + opmaak in 1 bestand)
In principe is alles natuurlijk XML: XSLT, XSL-FO, XHTML, je data bestanden enzovoorts. Je bedoelt uiteraard je data bestanden. Laten we dat dus XML-data noemen.

XSLT is niets meer en niets minder dan een transformatie taal voor XML. Je kan met behulp van XSLT dus XML transformeren, meestal naar een ander XML formaat zoals bijvoorbeeld (dus niet noodzakelijk) XHTML.

FOP is een renderer voor XSL Formatting Objects. Het kan dus een XSL-FO input renderen naar bijvoorbeeld een PDF document.

Meestal schrijf je zulke XSL-FO documenten niet met de hand omdat ze erg groot en verbose zijn. Over het algemeen wordt er XSLT gebruikt om XML-data te transformeren naar XSL-FO.
Als ik voor optie 1 kies dan krijg je dus dit:
fop -xsl test.xsl -xml test.xml -pdf test.pdf
Je -xsl en -xml optie is niets anders dan gebruikersgemak: in feite past FOP de XSL transformatie toe op de XML input en gaat daarna pas zelf echt aan de slag. Het resultaat van de transformatie moeten wel XSL Formatting Objects zijn en dat is een punt wat je volgens mij met name hebt gemist.
In mijn geval wordt de XML code gegeneerd door een programma. Met een editor (XMLSpy ?) moet een bijbehorend XSL bestand gemaakt worden.
XSL Transformaties kan je in principe in elke tekst editor schrijven, maar een editor die daarbij helpt kan wellicht handig zijn ja.
Vervolgens met FOP omzetten naar pdf of PostScript.
FOP kan dus alleen XSL Formatting Objects omzetten naar PDF of PostScript. Als je een xml en een xsl meegeeft, moet het resultaat van deze transformatie XSL-FO zijn.
Als dit niet zo is dan snap ik niet waarom FOP de optie: "fop -xsl test.xsl -xml test.xml -pdf test.pdf" heeft.
Gebruiksgemak :) . Je zou ook eerst een XSLT processor kunnen aanroepen en daarna het resultaat doorgeven aan FOP met de -fo optie.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


Verwijderd

Topicstarter
Ok, ik ben erin geslaagd om een XML data bestand en XSL opmaak bestand te maken en met FOP te converteren naar PDF en PS.

Echter ik wil nu een afbeelding toevoegen aan mijn xsl bestand:

code:
1
2
3
...
<fo:external-graphic height="100px" width="60px" src="file:linux.bmp"/> 
...


Als ik nu FOP aanroep:

code:
1
fop -xsl test.xsl -xml test.xml -pdf test.pdf


Echter FOP geeft de volgende foutmelding:
..
..
[INFO] [1]
[WARNING] Some static content could not fit in the area.
[INFO] [2]
[WARNING] Some static content could not fit in the area.
[INFO] Parsing of document complete, stopping renderer.
Als ik nu de pdf file open dan is alles ok behalve de afbeelding, die is namelijk afwezig.

Wat is het probleem.

  • tomato
  • Registratie: November 1999
  • Niet online
Waarschijnlijk past 100x60 pixels niet in het gebied waar je de afbeelding wilt plaatsen :?

Verwijderd

Topicstarter
tomato schreef op 04 February 2003 @ 16:14:
Waarschijnlijk past 100x60 pixels niet in het gebied waar je de afbeelding wilt plaatsen :?
Correct

Verwijderd

Topicstarter
Ik wil nu data uit een xml bestand mbv een xsl bestand in een tabel zetten en vervolgens via FOP omzetten in een pdf bestand.

Mijn xml bestand ziet er als volgt uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0"?>
<orders>
<order>
    <klantnr>12345</klantnr>
    <artikelnr>000098765</artikelnr>
    <omschrijving>CD-ROM speler</omschrijving>
    <aantal>5</aantal>
</order>
<order>
    <klantnr>12345</klantnr>
    <artikelnr>000098766</artikelnr>
    <omschrijving>DVD speler</omschrijving>
    <aantal>2</aantal>
</order>
</orders>



Mijn xsl bestand ziet er zo uit:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?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"
    version="1.0">
    
<xsl:template match="orders">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

<fo:layout-master-set>

<fo:simple-page-master master-name="all"
    page-height="29.7cm"
    page-width="21cm"
    margin-top="1cm"
    margin-bottom="1cm" 
    margin-left="1cm"
    margin-right="1cm">
        <fo:region-body
            margin-top="70px"
            margin-bottom="1.1cm"/>
        <fo:region-before
            extent="65px"/>
        <fo:region-after
            extent="1cm"/>
</fo:simple-page-master>

</fo:layout-master-set>

<fo:page-sequence master-reference="all" format="i">
<fo:static-content flow-name="xsl-region-before">
    <fo:block text-align="start" start-indent="60px" font-size="10pt" font-family="serif">
        Koptekst
    </fo:block>
</fo:static-content> 

<fo:static-content flow-name="xsl-region-after">
    <fo:block text-align="center" font-size="10pt" font-family="serif">
        Voettekst - Pagina (<fo:page-number/>)
      </fo:block>
</fo:static-content> 

<fo:flow flow-name="xsl-region-body">
    <!-- this defines a title level 1-->
      <fo:block font-size="18pt" 
            font-family="sans-serif" 
            line-height="24pt"
            space-after.optimum="15pt"
            background-color="blue"
            color="white"
            text-align="center"
            padding-top="3pt">
        Voorbeeld tabel
      </fo:block>
    
    <!-- table start -->
    <fo:table table-layout="fixed">
            <fo:table-column column-width="50mm"/>
        <fo:table-column column-width="50mm"/>
        <fo:table-column column-width="50mm"/>
        <fo:table-body>
            <xsl:apply-templates select="order"/>
        </fo:table-body>
    </fo:table>
    <!-- table end -->

    <!-- normal text -->
    <fo:block text-align="start" space-before="10pt">
        Einde  
    </fo:block>
</fo:flow>

</fo:page-sequence>
</fo:root>
</xsl:template>

<xsl:template match="order">
    <fo:block text-align="start" font-size="8pt" font-family="sans-serif">
        <fo:table-row>
            <xsl:apply-templates select="klantnr"/>
            <xsl:apply-templates select="artikelnr"/>
            <xsl:apply-templates select="omschrijving"/>
            <xsl:apply-templates select="aantal"/>
        </fo:table-row>
    </fo:block>
</xsl:template>

<xsl:template match="klantnr">
    <fo:table-cell border-width="1mm" border-style="solid">
        <fo:block>
            <fo:block text-align="start">
                <xsl:value-of select="."/>
            </fo:block>
        </fo:block>
    </fo:table-cell>
</xsl:template>

<xsl:template match="artikelnr">
    <fo:table-cell border-width="1mm" border-style="solid">
        <fo:block>
            <fo:block text-align="start">
                <xsl:value-of select="."/>
            </fo:block>
        </fo:block>
    </fo:table-cell>
</xsl:template>

<xsl:template match="omschrijving">
    <fo:table-cell border-width="1mm" border-style="solid">
        <fo:block>
            <fo:block text-align="start">
                <xsl:value-of select="."/>
            </fo:block>
        </fo:block>
    </fo:table-cell>
</fo:table-cell>
</xsl:template>

<xsl:template match="aantal">
    <fo:table-cell border-width="1mm" border-style="solid">
        <fo:block>
            <fo:block text-align="start">
                <xsl:value-of select="."/>
            </fo:block>
        </fo:block>
    </fo:table-cell>
</xsl:template>
</xsl:stylesheet>


I roep nu FOP aan:
FOP -xsl voorbeeld.xsl -xml voorbeeld.xml -pdf voorbeeld.pdf

FOP genereerd de volgende foutmelding:
[INFO] Using org.apache.xerces.parsers.SAXParser as SAX2 Parser
[Fatal Error] voorbeeld.xsl:116:3: The element type "xsl:template" must be terminated by the matching end-tag "</xsl:template>".
[ERROR] javax.xml.transform.TransformerConfigurationException: javax.xml.transform.TransformerException: org.xml.sax.SAXParseException: The element type "xsl:template" must be terminated by the matching end-tag "</xsl:template>".
Het lukt me wel om een tabel te maken als ik de data invul in het xsl bestand. Echter ik wil de data uit het xml bestand halen.

Weet iemand waar het probleem zit of hoe je een tabel kunt maken met data uit een xml bestand?

Verwijderd

Topicstarter
Ik heb de oplossing gevonden:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
......   
    <!-- table start -->
    <fo:table table-layout="fixed"> 
      <fo:table-column column-width="20mm"/> 
      <fo:table-column column-width="50mm"/> 
      <fo:table-column column-width="50mm"/> 
      <fo:table-column column-width="20mm"/> 
      <fo:table-body> 
    <fo:table-row> 
          <fo:table-cell border-width="0.1mm"><fo:block font-weight="bold">Klantnr:</fo:block></fo:table-cell> 
          <fo:table-cell border-width="0.1mm"><fo:block font-weight="bold">Artikelnr:</fo:block></fo:table-cell> 
          <fo:table-cell border-width="0.1mm"><fo:block font-weight="bold">Omschrijving:</fo:block></fo:table-cell> 
          <fo:table-cell border-width="0.1mm"><fo:block font-weight="bold">Aantal:</fo:block></fo:table-cell> 
      </fo:table-row> 
    <xsl:for-each select="orders/order"> 
        <fo:table-row> 
          <fo:table-cell border-width="0.1mm"><fo:block><xsl:value-of select="klantnr"/></fo:block></fo:table-cell> 
          <fo:table-cell border-width="0.1mm"><fo:block><xsl:value-of select="artikelnr"/></fo:block></fo:table-cell> 
          <fo:table-cell border-width="0.1mm"><fo:block><xsl:value-of select="omschrijving"/></fo:block></fo:table-cell> 
          <fo:table-cell border-width="0.1mm"><fo:block><xsl:value-of select="aantal"/></fo:block></fo:table-cell> 
        </fo:table-row> 
    </xsl:for-each> 
    </fo:table-body> 
    </fo:table> >
    <!-- table end -->
.....
Pagina: 1