Apache FOP – XMLファイルをFOファイルに変換するには


今回は、XMLファイルをFOファイルに変換してみます。

FOファイルに変換するXMLファイル(SampleXML2FO.xml)には、以下を

<?xml version="1.0" encoding="UTF-8"?>
<projectteam>
  <projectname>The Killer Application</projectname>
  <member>
    <name>John Doe</name>
    <function>lead</function>
    <email>jon.doe@killerapp.fun</email>
  </member>
  <member>
    <name>Paul Coder</name>
    <function>dev</function>
    <email>paul.coder@killerapp.fun</email>
  </member>
  <member>
    <name>Max Hacker</name>
    <function>dev</function>
    <email>max.hacker@killerapp.fun</email>
  </member>
  <member>
    <name>Donna Book</name>
    <function>doc</function>
    <email>donna.book@killerapp.fun</email>
  </member>
  <member>
    <name>Henry Tester</name>
    <function>qa</function>
    <email>henry.tester@killerapp.fun</email>
  </member>
</projectteam>

スタイルシート(SampleXML2FO.xsl)には、以下を使用します。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" exclude-result-prefixes="fo">
  <xsl:output method="xml" version="1.0" omit-xml-declaration="no" indent="yes"/>
  <xsl:param name="versionParam" select="'1.0'"/>
  <!-- ========================= -->
  <!-- root element: projectteam -->
  <!-- ========================= -->
  <xsl:template match="projectteam">
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <fo:layout-master-set>
        <fo:simple-page-master master-name="simpleA4" page-height="29.7cm" page-width="21cm" margin-top="2cm" margin-bottom="2cm" margin-left="2cm" margin-right="2cm">
          <fo:region-body/>
        </fo:simple-page-master>
      </fo:layout-master-set>
      <fo:page-sequence master-reference="simpleA4">
        <fo:flow flow-name="xsl-region-body">
          <fo:block font-size="16pt" font-weight="bold" space-after="5mm">Project: <xsl:value-of select="projectname"/>
          </fo:block>
          <fo:block font-size="12pt" space-after="5mm">Version <xsl:value-of select="$versionParam"/>
          </fo:block>
          <fo:block font-size="10pt">
            <fo:table table-layout="fixed" width="100%" border-collapse="separate">
              <fo:table-column column-width="4cm"/>
              <fo:table-column column-width="4cm"/>
              <fo:table-column column-width="5cm"/>
              <fo:table-body>
                <xsl:apply-templates select="member"/>
              </fo:table-body>
            </fo:table>
          </fo:block>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template>
  <!-- ========================= -->
  <!-- child element: member     -->
  <!-- ========================= -->
  <xsl:template match="member">
    <fo:table-row>
      <xsl:if test="function = 'lead'">
        <xsl:attribute name="font-weight">bold</xsl:attribute>
      </xsl:if>
      <fo:table-cell>
        <fo:block>
          <xsl:value-of select="name"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell>
        <fo:block>
          <xsl:value-of select="function"/>
        </fo:block>
      </fo:table-cell>
      <fo:table-cell>
        <fo:block>
          <xsl:value-of select="email"/>
        </fo:block>
      </fo:table-cell>
    </fo:table-row>
  </xsl:template>
</xsl:stylesheet>

XMLファイルをFOファイルに変換するサンプルプログラムです。

package net.tk_factory.sample.apache.fop;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Source;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import net.tk_factory.sample.AbstractSample;

import org.apache.log4j.Logger;

/**
 * Apache FOPを使用したサンプルプログラムです。<br/>
 * <br/>
 * <b>内容</b>
 * <ol type="1">
 * <li>XMLファイルをFOファイルに変換します。</li>
 * </ol>
 * @author Takafumi Kondo (TK Factory)
 */
public class SampleXML2FO extends AbstractSample
{
    /** クラス名 */
    private static final String CLASS_NAME =
        SampleXML2FO.class.getSimpleName();

    /** ロガー */
    private static final Logger LOGGER =
        Logger.getLogger(SampleXML2FO.class.getName());

    /** XMLファイル */
    private static final String XML_FILE_NAME =
        SAMPLE_FILE_DIRECTORY + CLASS_NAME + ".xml";

    /** スタイルシート */
    private static final String XSLT_FILE_NAME =
        SAMPLE_FILE_DIRECTORY + CLASS_NAME + ".xsl";

    /** FOファイル */
    private static final String FO_FILE_NAME =
        SAMPLE_FILE_DIRECTORY + CLASS_NAME + ".fo";

    /**
     * SampleXML2FOオブジェクトを構築すると、
     * UnsupportedOperationExceptionがスローされます。<br/>
     */
    protected SampleXML2FO()
    {
        throw new UnsupportedOperationException();
    }

    /**
     * mainメソッドです。<br/>
     *
     * @param args 引数
     */
    public static void main(String[] args)
    {
        LOGGER.info("[START]" + CLASS_NAME);

        OutputStream out = null;

        try
        {
            //すでにFOファイルが存在している場合は削除する
            deleteExistsFile(FO_FILE_NAME);

            //出力するFOファイル
            out = new FileOutputStream(FO_FILE_NAME);

            //変換元のXMLファイル
            Source xml = new StreamSource(XML_FILE_NAME);
            //変換元のスタイルシート
            Source xlst = new StreamSource(XSLT_FILE_NAME);

            //XML⇒XSL FOに変換する
            Result result = new StreamResult(out);
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer(xlst);
            transformer.transform(xml, result);
        }
        catch (IOException ioex)
        {
            LOGGER.error(getStackTrace(ioex));
        }
        catch (TransformerConfigurationException tce)
        {
            LOGGER.error(getStackTrace(tce));
        }
        catch (TransformerException te)
        {
            LOGGER.error(getStackTrace(te));
        }
        finally
        {
            try
            {
                if (out != null)
                {
                    out.close();
                }
            }
            catch (IOException ioex)
            {
                LOGGER.error(getStackTrace(ioex));
            }

            LOGGER.info("[E N D]" + CLASS_NAME);
        }
    }
}

上記のサンプルプログラムを実行して生成されたFOファイルは、以下のような感じになります。

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master margin-right="2cm" margin-left="2cm" margin-bottom="2cm" margin-top="2cm" page-width="21cm" page-height="29.7cm" master-name="simpleA4">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="simpleA4">
<fo:flow flow-name="xsl-region-body">
<fo:block space-after="5mm" font-weight="bold" font-size="16pt">Project: The Killer Application</fo:block>
<fo:block space-after="5mm" font-size="12pt">Version 1.0</fo:block>
<fo:block font-size="10pt">
<fo:table border-collapse="separate" width="100%" table-layout="fixed">
<fo:table-column column-width="4cm"/>
<fo:table-column column-width="4cm"/>
<fo:table-column column-width="5cm"/>
<fo:table-body>
<fo:table-row font-weight="bold">
<fo:table-cell>
<fo:block>John Doe</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>lead</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>jon.doe@killerapp.fun</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell>
<fo:block>Paul Coder</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>dev</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>paul.coder@killerapp.fun</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell>
<fo:block>Max Hacker</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>dev</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>max.hacker@killerapp.fun</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell>
<fo:block>Donna Book</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>doc</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>donna.book@killerapp.fun</fo:block>
</fo:table-cell>
</fo:table-row>
<fo:table-row>
<fo:table-cell>
<fo:block>Henry Tester</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>qa</fo:block>
</fo:table-cell>
<fo:table-cell>
<fo:block>henry.tester@killerapp.fun</fo:block>
</fo:table-cell>
</fo:table-row>
</fo:table-body>
</fo:table>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>

参考

関連記事

  1. コメント 0

  1. トラックバック 0

return top