What's the best way to exclude a node in an svg file when using xsl-fo to generate a pdf?
I have some SVG files that I'd like to create a PDF with. For simplicity lets assume each one represents one page in the PDF. There is a node in the SVG containing some text that I would like to exclude. How do I go about doing so? Here's a sample SVG file and fo to include it as a page in the PDF.
Lets say there exists a file named /home/dave/images/some_image.svg containing this:
<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(#so开发者_如何学JAVAme-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>
and now for a sample fo that uses it
<?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>
So this works fine for including the whole svg "as is". How can I exclude the text node?
<text id="some-text" x="235" y="181">This text needs to go</text>
As for the real files I'm using they reference a font that I won't need to include in the PDF and the text will be behind the image anyway thus not viewable.
Keeping <fo:external-graphic />
: XSLT pre-processing
If you want or need to keep the <fo:external-graphic />
approach, then you should certainly pre-process your SVG using XSLT, as suggested by Wivani
A copy-all template and a remove template should be enough, like:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text[@id='some-text']"/>
You can keep your FO as-is, maybe changing the SVG path to the new, pre-processed SVG:
<fo:external-graphic src='/home/dave/images/some_image_stripped.svg'/>
For more specific info, see other SO questions like:
- XSLT 1.0: copy everything except certain nodes according to value and variable
- XSL: how to copy a tree, but removing some nodes?
- How to copy everything as is and only remove a specific element
Alternative using <fo:instream-foreign-object />
If, on the other hand, you want to keep a one-step process, you can investigate at inlining you SVG in your XML-FO, using <fo:instream-foreign-object />
.
But this would likely require you to change your processing logic, creating the XML-FO by means of an XSL transformation from your SVG file. This could conflict with other requirements of yours.
You can have a look at Displaying SVG using XSLFO for more info on this technique.
精彩评论