XSL 样式 sheet for XML to XSL-FO
XSL style sheet for XML to XSL-FO
我需要将 XML 个文件转换为 PDF,将通过 XSL-FO 完成。
源 XML 文件有自己的结构和字典 (NITF),不应更改。我必须为这些文件创建特定的 XSL 样式器。在整个 XML 个元素中,我只需要几个:
文字
-
tables
images < media-reference mime-type="application/gif" source="foo.gif" >
到目前为止,我已经成功地转换了 XML 文件的文本部分。而且我可以处理只包含一个简单的 table 和固定列号的文件。当我尝试处理源文件中的文本和 tables 时,出现转换错误。
附加了(工作不正常的)样式器 my.xsl 以及源文件。错误有点
org.apache.fop.fo.ValidationException: "fo:table-body" 缺少子元素。所需内容模型:marker* (table-row+|table-cell+)
XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE nitf SYSTEM "nitf.dtd">
<nitf>
<head>
<title type="main">Sub-title 1</title>
<meta name="filetype" content="content"/>
<docdata><document-id id-string="123456" /></docdata>
</head>
<body>
<body.head>
<hedline><hl1>Sub-title 1</hl1></hedline>
</body.head>
<body.content>
<ul>
<li>Some long text 1</li><li>Some long text 2</li>
</ul>
<table id="0001.csv">
<tbody>
<tr>
<td colspan="4" class="tbh">Table tilte 1</td>
</tr>
<tr>
<td colspan="1" class="tbc"> </td>
<td colspan="1" class="tbc-r">Col title 1</td>
<td colspan="1" class="tbc-r">Col title 2</td>
<td colspan="1" class="tbc-r">Col title 3</td>
</tr>
<tr>
<td colspan="1" class="tbd">Row title 1</td>
<td colspan="1" class="tbd-r">cell text 1</td>
<td colspan="1" class="tbd-r">cell text 2</td>
<td colspan="1" class="tbd-r">cell text 3</td>
</tr>
<tr>
<td colspan="1" class="tbd">Row title 2</td>
<td colspan="1" class="tbd-r">cell text 4</td>
<td colspan="1" class="tbd-r">cell text 5</td>
<td colspan="1" class="tbd-r">cell text 6</td>
</tr>
<tr>
<td colspan="4" class="footnote">Some footnote</td>
</tr>
<tr>
<td colspan="4" class="source">One more footnote</td>
</tr>
</tbody>
</table>
<p class="text">Just a short text</p>
<ul>
<li>Some long text 3</li><li>Some long text 4</li>
</ul>
</body.content>
</body>
XSL:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="nitf">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master page-height="297mm" page-width="210mm"
margin="5mm 25mm 5mm 25mm" master-name="simpleA4">
<fo:region-body margin="20mm 0mm 20mm 0mm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<!-- NOTE: text part is OK! -->
<fo:page-sequence master-reference="simpleA4">
<fo:flow flow-name="xsl-region-body" >
<fo:block>
<xsl:apply-templates select="head"/>
<!--xsl:apply-templates select="body"/ If it's uncommented, the table is not seen-->
</fo:block>
<fo:block>
<fo:table table-layout="fixed" border-style="solid">
<xsl:apply-templates select="tr" mode="theader"/>
<xsl:apply-templates select="tr" mode="tbody"/>
<fo:table-body>
<xsl:apply-templates select="body/table/tbody/tr"/>
</fo:table-body>
</fo:table>
</fo:block>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="tr">
<fo:table-row>
<xsl:apply-templates select="td"/>
</fo:table-row>
</xsl:template>
<xsl:template match="td">
<fo:table-cell border-style="solid">
<fo:block><xsl:value-of select="."/></fo:block>
</fo:table-cell>
</xsl:template>
<!-- text -->
<xsl:template match="head">
<fo:inline font-weight="bold">
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
<xsl:template match="body.head">
<fo:inline font-weight="bold">
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
<xsl:template match="body.content">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="p">
<fo:block>
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="b">
<fo:inline font-weight="bold">
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
</xsl:stylesheet >
Google 是你的朋友。我搜索了 NITF XSL FO 并找到了这个 https://github.com/ydirson/serna-free/tree/master/serna/dist/plugins/nitf/nitf-xsl-serna
如果您使用的是行业标准 XML,那么 XSL 可能存在 HTML,许多 XSL FO。
我从 Github 克隆并下载了该项目。 XSL 在那里并引用了其他一些。您只需要 "dist" 目录及以下目录,但其中还有很多很多东西您不需要。实际上,如果您检查根 "nitf.xsl",您会看到:
<xsl:import href="../../../xml/stylesheets/xslbricks/fo/fonts.xsl"/>
<xsl:import href="../../../xml/stylesheets/xslbricks/fo/common.xsl"/>
<xsl:import href="../../../xml/stylesheets/xslbricks/fo/layoutsetup.xsl"/>
<xsl:import href="../../../xml/stylesheets/xslbricks/fo/default-elements.xsl"/>
<xsl:import href="../../../xml/stylesheets/xslbricks/fo/page-sizes.xsl"/>
<xsl:import href="../../../xml/stylesheets/xslbricks/fo/xhtml-tables.xsl"/>
<xsl:include href="nitf-param.xsl"/>
<xsl:include href="nitf-common.xsl"/>
<xsl:include href="nitf-struct.xsl"/>
<xsl:include href="nitf-meta.xsl"/>
<xsl:include href="nitf-blocks.xsl"/>
<xsl:include href="nitf-inlines.xsl"/>
<xsl:include href="nitf-lists.xsl"/>
<xsl:include href="nitf-images.xsl"/>
<xsl:include href="nitf-tables.xsl"/>
那些 imported/included 文件将代表所有 XSL(除非其中一些还引用其他文件,我没有检查)。
运行 你上面的 XML (在添加你省略的关闭 标签之后)并使用 Apache FOP 将生成的 FO 格式化为 PDF,它产生这个:
现在,如果您愿意,您当然可以检查这些 XSL 以观察您在 XSL 中做错了什么,但是正如您所看到的,已经有很多工作投入到这些 XSL 中。我总是尽量避免 "reinventing the wheel."
要重新组织所有这些,您只需隔离所需的 XSL,编辑主 "nitf.xsl" 以根据需要在一个目录中引用所有 XSL。我这样做了,它仍然有效(所以 none 我没有检查引用其他的 XSL),我的目录现在只有以下内容,我删除了所有其他内容:
我需要将 XML 个文件转换为 PDF,将通过 XSL-FO 完成。 源 XML 文件有自己的结构和字典 (NITF),不应更改。我必须为这些文件创建特定的 XSL 样式器。在整个 XML 个元素中,我只需要几个:
文字
-
tables
images < media-reference mime-type="application/gif" source="foo.gif" >
到目前为止,我已经成功地转换了 XML 文件的文本部分。而且我可以处理只包含一个简单的 table 和固定列号的文件。当我尝试处理源文件中的文本和 tables 时,出现转换错误。 附加了(工作不正常的)样式器 my.xsl 以及源文件。错误有点
org.apache.fop.fo.ValidationException: "fo:table-body" 缺少子元素。所需内容模型:marker* (table-row+|table-cell+)
XML:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE nitf SYSTEM "nitf.dtd"> <nitf> <head> <title type="main">Sub-title 1</title> <meta name="filetype" content="content"/> <docdata><document-id id-string="123456" /></docdata> </head> <body> <body.head> <hedline><hl1>Sub-title 1</hl1></hedline> </body.head> <body.content> <ul> <li>Some long text 1</li><li>Some long text 2</li> </ul> <table id="0001.csv"> <tbody> <tr> <td colspan="4" class="tbh">Table tilte 1</td> </tr> <tr> <td colspan="1" class="tbc"> </td> <td colspan="1" class="tbc-r">Col title 1</td> <td colspan="1" class="tbc-r">Col title 2</td> <td colspan="1" class="tbc-r">Col title 3</td> </tr> <tr> <td colspan="1" class="tbd">Row title 1</td> <td colspan="1" class="tbd-r">cell text 1</td> <td colspan="1" class="tbd-r">cell text 2</td> <td colspan="1" class="tbd-r">cell text 3</td> </tr> <tr> <td colspan="1" class="tbd">Row title 2</td> <td colspan="1" class="tbd-r">cell text 4</td> <td colspan="1" class="tbd-r">cell text 5</td> <td colspan="1" class="tbd-r">cell text 6</td> </tr> <tr> <td colspan="4" class="footnote">Some footnote</td> </tr> <tr> <td colspan="4" class="source">One more footnote</td> </tr> </tbody> </table> <p class="text">Just a short text</p> <ul> <li>Some long text 3</li><li>Some long text 4</li> </ul> </body.content> </body>
XSL:
<?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet version="1.0" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" indent="yes"/> <xsl:template match="nitf"> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <fo:layout-master-set> <fo:simple-page-master page-height="297mm" page-width="210mm" margin="5mm 25mm 5mm 25mm" master-name="simpleA4"> <fo:region-body margin="20mm 0mm 20mm 0mm"/> </fo:simple-page-master> </fo:layout-master-set> <!-- NOTE: text part is OK! --> <fo:page-sequence master-reference="simpleA4"> <fo:flow flow-name="xsl-region-body" > <fo:block> <xsl:apply-templates select="head"/> <!--xsl:apply-templates select="body"/ If it's uncommented, the table is not seen--> </fo:block> <fo:block> <fo:table table-layout="fixed" border-style="solid"> <xsl:apply-templates select="tr" mode="theader"/> <xsl:apply-templates select="tr" mode="tbody"/> <fo:table-body> <xsl:apply-templates select="body/table/tbody/tr"/> </fo:table-body> </fo:table> </fo:block> </fo:flow> </fo:page-sequence> </fo:root> </xsl:template> <xsl:template match="tr"> <fo:table-row> <xsl:apply-templates select="td"/> </fo:table-row> </xsl:template> <xsl:template match="td"> <fo:table-cell border-style="solid"> <fo:block><xsl:value-of select="."/></fo:block> </fo:table-cell> </xsl:template> <!-- text --> <xsl:template match="head"> <fo:inline font-weight="bold"> <xsl:apply-templates/> </fo:inline> </xsl:template> <xsl:template match="body.head"> <fo:inline font-weight="bold"> <xsl:apply-templates/> </fo:inline> </xsl:template> <xsl:template match="body.content"> <xsl:apply-templates/> </xsl:template> <xsl:template match="p"> <fo:block> <xsl:apply-templates/> </fo:block> </xsl:template> <xsl:template match="b"> <fo:inline font-weight="bold"> <xsl:apply-templates/> </fo:inline> </xsl:template> </xsl:stylesheet >
Google 是你的朋友。我搜索了 NITF XSL FO 并找到了这个 https://github.com/ydirson/serna-free/tree/master/serna/dist/plugins/nitf/nitf-xsl-serna
如果您使用的是行业标准 XML,那么 XSL 可能存在 HTML,许多 XSL FO。
我从 Github 克隆并下载了该项目。 XSL 在那里并引用了其他一些。您只需要 "dist" 目录及以下目录,但其中还有很多很多东西您不需要。实际上,如果您检查根 "nitf.xsl",您会看到:
<xsl:import href="../../../xml/stylesheets/xslbricks/fo/fonts.xsl"/> <xsl:import href="../../../xml/stylesheets/xslbricks/fo/common.xsl"/> <xsl:import href="../../../xml/stylesheets/xslbricks/fo/layoutsetup.xsl"/> <xsl:import href="../../../xml/stylesheets/xslbricks/fo/default-elements.xsl"/> <xsl:import href="../../../xml/stylesheets/xslbricks/fo/page-sizes.xsl"/> <xsl:import href="../../../xml/stylesheets/xslbricks/fo/xhtml-tables.xsl"/> <xsl:include href="nitf-param.xsl"/> <xsl:include href="nitf-common.xsl"/> <xsl:include href="nitf-struct.xsl"/> <xsl:include href="nitf-meta.xsl"/> <xsl:include href="nitf-blocks.xsl"/> <xsl:include href="nitf-inlines.xsl"/> <xsl:include href="nitf-lists.xsl"/> <xsl:include href="nitf-images.xsl"/> <xsl:include href="nitf-tables.xsl"/>
那些 imported/included 文件将代表所有 XSL(除非其中一些还引用其他文件,我没有检查)。
运行 你上面的 XML (在添加你省略的关闭 标签之后)并使用 Apache FOP 将生成的 FO 格式化为 PDF,它产生这个:
现在,如果您愿意,您当然可以检查这些 XSL 以观察您在 XSL 中做错了什么,但是正如您所看到的,已经有很多工作投入到这些 XSL 中。我总是尽量避免 "reinventing the wheel."
要重新组织所有这些,您只需隔离所需的 XSL,编辑主 "nitf.xsl" 以根据需要在一个目录中引用所有 XSL。我这样做了,它仍然有效(所以 none 我没有检查引用其他的 XSL),我的目录现在只有以下内容,我删除了所有其他内容: