home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-cocoon-addon-1.4.9-installer.exe / howto-html-pdf-publishing.xml < prev    next >
Encoding:
Extensible Markup Language  |  2004-07-12  |  14.8 KB  |  442 lines

  1. <?xml version="1.0"?>
  2. <!--
  3.   Copyright 1999-2004 The Apache Software Foundation
  4.  
  5.   Licensed under the Apache License, Version 2.0 (the "License");
  6.   you may not use this file except in compliance with the License.
  7.   You may obtain a copy of the License at
  8.  
  9.       http://www.apache.org/licenses/LICENSE-2.0
  10.  
  11.   Unless required by applicable law or agreed to in writing, software
  12.   distributed under the License is distributed on an "AS IS" BASIS,
  13.   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.   See the License for the specific language governing permissions and
  15.   limitations under the License.
  16. -->
  17. <!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.0//EN" "document-v10.dtd">
  18.  
  19. <document>
  20.  <header>
  21.   <title>How to Publish XML Documents in HTML and PDF</title>
  22.   <authors>
  23.    <person name="Bertrand Delacrétaz" email="bdelacretaz@codeconsult.ch"/>
  24.   </authors>
  25.  </header>
  26.  
  27.  <body>
  28.  
  29. <s1 title="Overview">
  30. <p>
  31. This How-To shows you how to publish XML documents in HTML and PDF using Cocoon. It requires no 
  32. prior knowledge of Cocoon, XSLT or XSL-FO.
  33. </p>
  34. <p>
  35. It has been updated for Cocoon 2.1, which does not require the use of the <em>mount</em> directory anymore.
  36. </p>
  37. </s1>
  38.  
  39. <s1 title="Purpose">
  40. <p>
  41. You will learn how to build a simple pipeline that converts XML documents on-the-fly to HTML or PDF using simple 
  42. XSLT transforms. This is similar to the <code>hello.html</code> and <code>hello.pdf</code> samples of the standard Cocoon installation. However, this How-To teaches you how to build these mechanisms yourself. Thus, you will get a better feel of how Cocoon publishing really works.
  43. </p>
  44. </s1>
  45.  
  46. <s1 title="Intended Audience">
  47. <p>
  48. Beginning Cocoon users who want to learn how to publish HTML and/or PDF documents from XML data.
  49. </p>
  50. </s1>
  51.  
  52. <s1 title="Prerequisites">
  53. <p>Here's what you need:</p>  
  54.  
  55. <ul>
  56. <li>Cocoon must be running on your system. The steps below have been tested with Cocoon 2.1m3-dev, but they should work with any 2.1 version.</li>
  57. <li>This document assumes a standard installation where Cocoon is started by the <em>cocoon.sh</em> (or cocoon.bat) script and where
  58. <code>http://localhost:8888/</code> points to the <em>Welcome to Apache Cocoon</em> page.
  59. <br />
  60. If your installation runs on a different URL, you will have to adjust
  61. the URLs provided throughout this How-To as necessary. 
  62. </li>
  63. <li>You must be able to create and edit XML files in the main directory of the Cocoon installation.
  64. When started from cocoon.sh, this directory is <code>build/webapp</code> under the directory that contains cocoon.sh.
  65. </li>
  66. </ul>
  67. <note>You will not need a fancy XML editor for this How-To. Copying and pasting the sample code snippets into any text editor
  68. will do.</note>
  69. <note>
  70. Running "build clean" deletes everything under build/webapp, make sure to save your example files if you
  71. need to do a clean build.
  72.  </note>
  73.  
  74. </s1>
  75.  
  76. <s1 title="Steps">
  77. <p>
  78. Here's how to proceed.
  79. </p>
  80.  
  81. <s2 title="1. Create the work directory" >
  82. <p>
  83. Under <code>build/webapp</code>, create a new directory and name it <code>html-pdf</code>.
  84. All files used by this How-To will reside in this directory.
  85. </p>
  86. <p>
  87. At this point, <code>http://localhost:8888/html-pdf/</code> should display an error page saying <em>Resource not found</em>,
  88. indicating that the file <em>build/webapp/html-pdf/sitemap.xmap</em> was not found. This is normal, as the newly
  89. created directory does not yet contain the required sitemap file.
  90. </p>
  91. </s2>
  92.  
  93. <s2 title="2. Create the XML example documents" >
  94. <p>
  95. To keep it simple we will use two small XML files as our data sources.
  96. Later, you will probably use additional data sources like live XML feeds, databases, and others.</p>
  97. <p>
  98. In the <code>html-pdf</code> directory, create the following two files, and name them exactly as
  99. shown.
  100. </p>
  101.  
  102. <p>
  103. Contents of file <strong>pageOne.xml</strong>:
  104. </p>
  105.        <source><![CDATA[
  106. <?xml version="1.0" encoding="iso-8859-1"?>
  107. <page>
  108. <title>This is the pageOne.xml example</title>
  109. <s1 title="Section one">
  110.     <p>This is the text of section one</p>
  111. </s1>
  112. </page>
  113.         ]]></source>
  114.  
  115. <p>
  116. Contents of file <strong>pageTwo.xml</strong>:
  117. </p>
  118.        <source><![CDATA[
  119. <?xml version="1.0" encoding="iso-8859-1"?>
  120. <page>
  121. <title>This is the pageTwo.xml example</title>
  122. <s1 title="Yes, it works">
  123.     <p>Now you're hopefully seeing pageTwo in HTML or PDF</p>
  124. </s1>
  125. </page>
  126.         ]]></source>
  127.         
  128. <note>
  129. Be careful about the use of lower/uppercase in filenames if you're working on a Unix or Linux system. 
  130. On such systems, <code>thisFile.xml</code> is not the same as <code>Thisfile.xml</code>.
  131. </note>
  132. <note>
  133. To avoid any errors, use copy/paste when creating XML documents from examples on this page.
  134. </note>
  135. <note>
  136. Do not leave spaces at the start of XML files. The <?xml... processing instruction must
  137. be the first character in the file.
  138. </note>
  139. </s2>
  140.  
  141. <s2 title="3. Create the XSLT transform for HTML" >
  142. <p>
  143. The most common way of producing HTML in Cocoon is to use <strong>XSLT transforms</strong> to select and convert 
  144. the appropriate elements of the input documents.
  145. </p>
  146.  
  147. <p>
  148. Copy the file shown below to the <code>html-pdf</code> directory alongside your XML documents, naming it
  149. <strong>doc2html.xsl</strong>
  150. </p>
  151.  
  152.        <source><![CDATA[
  153. <?xml version="1.0" encoding="iso-8859-1"?>
  154. <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  155.  
  156. <!-- generate HTML skeleton on root element -->
  157. <xsl:template match="/">
  158.   <html>
  159.     <head>
  160.       <title><xsl:apply-templates select="page/title"/></title>
  161.     </head>
  162.     <body>
  163.         <xsl:apply-templates/>
  164.     </body>
  165.   </html>
  166. </xsl:template>
  167.  
  168. <!-- story is used later by the Meerkat example -->
  169. <xsl:template match="p|story">
  170.     <p><xsl:apply-templates/></p>
  171. </xsl:template>
  172.  
  173. <!-- convert sections to HTML headings -->
  174. <xsl:template match="s1">
  175.     <h1><xsl:apply-templates select="@title"/></h1>
  176.     <xsl:apply-templates/>
  177. </xsl:template>
  178.  
  179. </xsl:stylesheet>     
  180. ]]></source>
  181. <note>       
  182. Basically what this does is generate an HTML skeleton and convert the input markup to HTML. We won't go
  183. into details here. Rather, our goal is to show you how the components of the publishing chain are combined.  
  184. </note>
  185.  
  186. </s2>
  187.  
  188. <s2 title="4. Create the sitemap" >
  189. <p>
  190. We now have documents to publish and an XSLT transform to convert them to our HTML output format.
  191. What's left is to connect them in a <strong>processing pipeline</strong>. Then, the <strong>sitemap</strong> can select the pipeline based on the details of the browser request.
  192. </p>
  193.  
  194. <p>
  195. To tell Cocoon how to process requests made to <code>html-pdf</code>, 
  196. copy the following snippet to a file named <strong>sitemap.xmap</strong> in the 
  197. <code>html-pdf</code> subdirectory.
  198. </p>
  199.  
  200.        <source><![CDATA[
  201. <?xml version="1.0" encoding="iso-8859-1"?>
  202. <map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
  203.  
  204.     <!-- define the Cocoon processing pipelines -->
  205.     <map:pipelines>
  206.         <map:pipeline>
  207.             <!-- respond to *.html requests with
  208.                  our docs processed by doc2html.xsl -->
  209.             <map:match pattern="*.html">
  210.                 <map:generate src="{1}.xml"/>
  211.                 <map:transform src="doc2html.xsl"/>
  212.                 <map:serialize type="html"/>
  213.             </map:match>
  214.  
  215.             <!-- later, respond to *.pdf requests with
  216.                  our docs processed by doc2pdf.xsl -->
  217.             <map:match pattern="*.pdf">
  218.                 <map:generate src="{1}.xml"/>
  219.                 <map:transform src="doc2pdf.xsl"/>
  220.                 <map:serialize type="fo2pdf"/>
  221.             </map:match>
  222.         </map:pipeline>
  223.     </map:pipelines>
  224. </map:sitemap>
  225.         ]]></source>
  226.         
  227. <note>The important thing here is the first <strong>map:match</strong> element, which tells Cocoon how to process
  228. requests ending in *.html in this directory. Again, we won't go into details here, but that's where it happens.
  229. </note>
  230. <note>The above sitemap is already configured for PDF publishing. However, this capability is not fully functional at this time because we haven't created the required XSLT transform yet.</note> 
  231.        
  232. </s2>
  233.  
  234. <s2 title="5. Test the HTML publishing" >
  235. <p>
  236. At this point you should be able to display the results in HTML: 
  237. </p>
  238. <ul>
  239. <li>
  240. <code>http://localhost:8888/html-pdf/pageOne.html</code>
  241. should display the first page with "Section one" in big letters.
  242. </li>
  243. <li>
  244. <code>http://localhost:8888/html-pdf/pageTwo.html</code>
  245. should display the second page with "Yes it works" in big letters.
  246. </li>
  247. </ul>
  248. <note>If this doesn't work, you might want to double check the above steps first, and then look at the Cocoon
  249. logs (see the Cocoon wiki for information about the logs).
  250. </note>
  251. <note>
  252. To convince yourself that the HTML data is generated dynamically, you can try to edit the pageXXX.xml source documents
  253. (keeping them well-formed),
  254. and refresh the browser to see the effect of your changes.
  255. </note>
  256. </s2>
  257.  
  258.  
  259. <s2 title="6. Create the XSLT transform for PDF" >
  260. <p>
  261. PDF documents are created via XSL-FO documents which are XML documents that use a specific page-description
  262. vocabulary. (See <link href="#references">References</link> below for more info). The actual conversion to PDF is done by the 
  263. <code>PdfSerializer</code> which uses software from <link href="http://xml.apache.org/fop">FOP</link>, another Apache
  264. Software Foundation project.   
  265. </p>
  266.  
  267. <p>
  268. To activate the PDF conversion, copy the code snippet shown below to the <code>html-pdf</code> directory along with your XML documents, and name it
  269. <strong>doc2pdf.xsl</strong>
  270. </p>
  271.  
  272.        <source><![CDATA[
  273. <?xml version="1.0" encoding="iso-8859-1"?>
  274. <xsl:stylesheet 
  275.     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  276.     xmlns:fo="http://www.w3.org/1999/XSL/Format"
  277. >
  278.     <!-- generate PDF page structure -->
  279.     <xsl:template match="/">
  280.         <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
  281.             <fo:layout-master-set>
  282.                 <fo:simple-page-master master-name="page"
  283.                   page-height="29.7cm" 
  284.                   page-width="21cm"
  285.                   margin-top="1cm" 
  286.                   margin-bottom="2cm" 
  287.                   margin-left="2.5cm" 
  288.                   margin-right="2.5cm"
  289.                 >
  290.                     <fo:region-before extent="3cm"/>
  291.                     <fo:region-body margin-top="3cm"/>
  292.                     <fo:region-after extent="1.5cm"/>
  293.                 </fo:simple-page-master>
  294.  
  295.                 <fo:page-sequence-master master-name="all">
  296.                     <fo:repeatable-page-master-alternatives>
  297.                         <fo:conditional-page-master-reference 
  298.                            master-reference="page" page-position="first"/>
  299.                     </fo:repeatable-page-master-alternatives>
  300.                 </fo:page-sequence-master>
  301.             </fo:layout-master-set>
  302.  
  303.             <fo:page-sequence master-reference="all">
  304.                 <fo:flow flow-name="xsl-region-body">
  305.                     <fo:block><xsl:apply-templates/></fo:block>
  306.                 </fo:flow>
  307.             </fo:page-sequence>
  308.         </fo:root>
  309.     </xsl:template>
  310.  
  311.     <!-- process paragraphs -->
  312.     <xsl:template match="p">
  313.         <fo:block><xsl:apply-templates/></fo:block>
  314.     </xsl:template>
  315.  
  316.     <!-- convert sections to XSL-FO headings -->
  317.     <xsl:template match="s1">
  318.         <fo:block font-size="24pt" color="red" font-weight="bold">
  319.             <xsl:apply-templates select="@title"/>
  320.         </fo:block>
  321.         <xsl:apply-templates/>
  322.     </xsl:template>
  323.  
  324. </xsl:stylesheet>
  325. ]]>
  326.        </source>
  327. <note>This file is already referenced by the sitemap we created, so no additional configuration is needed.</note>       
  328. </s2>
  329.  
  330. <s2 title="5. Test the PDF publishing" >
  331. <p>
  332. At this point you should be able to display the results in PDF in addition to the existing HTML versions: 
  333. </p>
  334. <ul>
  335. <li>
  336. <code>http://localhost:8888/html-pdf/pageOne.pdf</code>
  337. should display the first page with "Section one" in big red letters.
  338. </li>
  339. <li>
  340. <code>http://localhost:8888/html-pdf/pageTwo.pdf</code>
  341. should display the second page with "Yes it works" in big red letters.
  342. </li>
  343. </ul>
  344. </s2>
  345.  
  346. </s1>
  347.  
  348. <s1 title="Summary">
  349. <p>
  350. I hope you're beginning to see that publishing PDF and HTML documents in Cocoon is not too complicated, once you know what goes where. 
  351. </p>
  352. <p>
  353. The nice thing is that all of our huge corpus
  354. of XML documents (actually, only two documents right now, but that's a start... ) is processed by just two XSLT transforms, one
  355. for each target format.
  356. </p>
  357. <p>
  358. If you need to change the appearance of the published documents, you have to change only these two XSLT transforms. There's no need to touch the source documents.
  359. </p>
  360. </s1>
  361.  
  362. <s1 title="Tips">
  363. <s2 title="Tip 1: Dynamic XML data">
  364. <p>
  365. Using dynamic XML as the data source is very easy because the Cocoon FileGenerator can read URLs as well. 
  366. </p>
  367. <p>
  368. If you add the map:match element shown in bold below <strong>before</strong> the existing map:match elements in your sitemap.xmap file, requesting
  369. <code>http://localhost:8888/html-pdf/meerkat.html</code>
  370. should display real-time news from Meerkat (assuming an Internet connection to Meerkat is available).
  371. </p>
  372. <p>
  373. The news will be displayed in a very rough format. However, this can be improved by writing a 
  374. specific XSLT transform for this Meerkat data and using it, instead of doc2html.xsl, in the meerkat.html pipeline.  
  375. </p>
  376.  
  377. <source>
  378. <![CDATA[
  379. ...
  380. <map:pipeline>
  381. ]]>
  382. <strong>
  383. <![CDATA[
  384. <map:match pattern="meerkat.html">
  385.     <map:generate src="http://www.oreillynet.com/meerkat/?_fl=xml"/>
  386.     <map:transform src="doc2html.xsl"/>
  387.     <map:serialize type="html"/>
  388. </map:match>
  389. ]]>
  390. </strong>
  391. <![CDATA[
  392. <map:match pattern="*.html">
  393. etc...
  394. ]]>
  395. </source>
  396. </s2>
  397.  
  398. <s2 title="Tip 2: Two-step conversion">
  399. <p>
  400. When you are generating multiple formats from a single data source, it is often a good idea to generate 
  401. an intermediate <strong>logical document</strong> that describes the output in a format-neutral way.
  402. </p>
  403. <p>
  404. This is obviously not needed in our simple example. If you're aiming for more complicated 
  405. publishing tasks, then you might want to read about this "publishing pattern" in Martin Fowler's 
  406. <link href="http://martinfowler.com/eaaCatalog/twoStepView.html">Two Step View</link>
  407. article.
  408. </p>
  409. </s2>
  410.  
  411. </s1>
  412.  
  413. <s1 title="References">
  414. <anchor id="references"/>
  415. <p>
  416. To go further, you will need to learn about the following technologies and tools.
  417. </p>
  418. <ul>
  419. <li>
  420. Learning  
  421. <link href="http://cocoon.apache.org/2.1/userdocs/concepts/index.html">
  422. Cocoon concepts</link> will help you understand how the sitemap, generators, transformers, and serializers work.
  423. </li> 
  424. <li>
  425. Learning about <link href="http://www.w3.org/Style/XSL/">XSLT</link> will enable you to write your own transforms to 
  426. generate HTML, PDF or other formats from XML data. 
  427. Information about XSL-FO is available at the same address.  
  428. </li>
  429. </ul>
  430. </s1>
  431.  
  432. <s1 title="Comments">
  433. <p>
  434. Care to comment on this How-To? Got another tip? 
  435. Help keep this How-To relevant by passing along any useful feedback to the author,
  436. <link href="mailto:bdelacretaz@apache.org">Bertrand Delacrétaz</link>.
  437. </p>
  438. </s1>
  439.  
  440. </body>
  441. </document>
  442.