使用xsl-fo生成pdf时,在svg文件中排除节点的最佳方法是什么?

时间:2011-07-15 22:15:19

标签: xml pdf svg xsl-fo apache-fop

我有一些我想创建PDF的SVG文件。为简单起见,我们假设每个代表PDF中的一个页面。 SVG中有一个节点包含一些我想要排除的文本。我该怎么做呢?这是一个示例SVG文件,可以将其作为PDF中的页面包含。

假设存在一个名为/home/dave/images/some_image.svg的文件,其中包含:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="470" height="363" xml:space="preserve">
  <g clip-path="url(#some-path)">
    <rect id="some-rect" fill="#FFFFFF" stroke="#666" height="363" width="470" opacity="1" x="0" y="0"/>
    <defs id="some-defs">
      <clipPath id="some-path" x="0" y="0" width="100%" height="100%">
        <rect height="363" x="0" y="0" width="470" fill="#fff"/>
      </clipPath>
    </defs>
    <g id="some-group">
      <path id="a-path"/>
      <g id="a-container">
        <text id="some-text" x="235" y="181">This text needs to go</text>
        <image x="-2000" y="-1500" width="4000" height="3000" xlink:href="http://www.somewebsite.com/image.jpg" id="some-img"/>
      </g>
    </g>
  </g>
</svg>

现在是使用它的样本

<?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 master-name="page" margin="0pt"
                           page-height="363pt" page-width="470pt">
      <fo:region-body />
    </fo:simple-page-master>
  </fo:layout-master-set>

  <fo:page-sequence master-reference="page">
    <fo:flow flow-name="xsl-region-body">
      <fo:block>
        <fo:external-graphic 
            src='/home/dave/images/some_image.svg'/>
      </fo:block>
    </fo:flow>
  </fo:page-sequence>

</fo:root>

所以这适用于包括整个svg“按原样”。如何排除文本节点?

<text id="some-text" x="235" y="181">This text needs to go</text>

至于我正在使用的真实文件,它们引用了一种我不需要包含在PDF中的字体,文本将在图像后面,因此无法查看。

1 个答案:

答案 0 :(得分:1)

保持<fo:external-graphic />:XSLT预处理

如果您想要或需要保持<fo:external-graphic />方法,那么您应该使用XSLT预处理SVG,如Wivani

所示

复制所有模板和删除模板应该足够了,例如:

<xsl:template match="node()|@*">
  <xsl:copy>
     <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="text[@id='some-text']"/>

您可以按原样保留您的FO,也许可以将SVG路径更改为新的预处理SVG:

<fo:external-graphic src='/home/dave/images/some_image_stripped.svg'/>

有关更具体的信息,请参阅其他SO问题:

使用<fo:instream-foreign-object />

的备选方案

另一方面,如果您希望保持一个步骤,则可以使用<fo:instream-foreign-object />调查在XML-FO中向SVG内嵌SVG。

但这可能需要您更改处理逻辑,通过来自 SVG文件的XSL转换创建XML-FO。这可能与您的其他要求相冲突。

您可以查看Displaying SVG using XSLFO了解有关此技术的更多信息。