我需要将XML文件转换为PDF,然后通过XSL-FO进行。 源XML文件具有其结构和字典(NITF),因此不应更改。我必须为这些文件创建特定的XSL样式器。在整个XML元素中,我只需要几个:
文本
表格
图像<媒体参考mime-type =“ application / gif” source =“ foo.gif”>
到目前为止,我已经设法转换了XML文件的文本部分。而且我可以处理仅包含具有固定列号的简单表的文件。当我尝试处理源文件中的文本和表格时,出现转换错误。 附带了(无效的)样式器my.xsl以及源文件。错误是
org.apache.fop.fo.ValidationException:“ fo:table-body”缺少子元素。必需的内容模型:标记*(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 >
答案 0 :(得分:2)
Google是您的朋友。我搜索了NITF XSL FO,发现了这个https://github.com/ydirson/serna-free/tree/master/serna/dist/plugins/nitf/nitf-xsl-serna
如果您使用的是行业标准XML,则XSL可能存在于HTML中,而许多XSL则存在于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"/>
那些导入/包含的文件将代表所有XSL(除非其中一些也引用了其他文件,我没有检查)。
在上面运行您的XML(添加省略的close 标记之后),然后使用Apache FOP将生成的FO格式化为PDF,它产生以下结果:
现在,您当然可以根据需要检查那些XSL,以查看您在XSL中做错了什么,但是正如您所看到的那样,这些XSL已经投入了很多工作。我总是会尽量避免“重新发明轮子”。
要重新组织所有这些,您可以仅隔离所需的XSL,如果需要,可以编辑主“ nitf.xsl”以在一个目录中引用所有这些XSL。我这样做了,它仍然可以正常工作(所以我没有检查过的XSL都没有参考其他XSL),我的目录现在只有以下内容,并且删除了其他所有内容: