Каков наилучший способ исключить узел в файле svg при использовании xsl-fo для создания PDF-файла?

У меня есть несколько файлов SVG, из которых я хотел бы создать PDF. Для простоты предположим, что каждый из них представляет одну страницу в 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, и текст в любом случае будет за изображением, поэтому его нельзя будет просмотреть.


person Khorkrak    schedule 15.07.2011    source источник
comment
Как вы создаете XSL-FO?   -  person Daniel Haley    schedule 16.07.2011
comment
Только вручную пока. Позже мне придется каким-то образом программно сгенерировать xsl-fo или xslt - возможно, с помощью python и lxml. Таким образом, при этом я мог бы обработать файлы svg и удалить ненужные узлы, но мне интересно, есть ли более элегантное декларативное решение с использованием xsl.   -  person Khorkrak    schedule 16.07.2011
comment
Я не гуру FO, но я бы пошел на удаление нежелательного узла на шаге XSLT. Svg — это, в конце концов, форма xml.   -  person Wivani    schedule 18.07.2011


Ответы (1)


Сохранение <fo:external-graphic />: предварительная обработка XSLT

Если вы хотите или должны сохранить подход <fo:external-graphic />, вам обязательно следует предварительно обработать SVG с помощью XSLT, как это предлагает 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 />

Если, с другой стороны, вы хотите сохранить одноэтапный процесс, вы можете попытаться встроить свой SVG в свой XML-FO, используя <fo:instream-foreign-object />.

Но для этого, вероятно, потребуется изменить логику обработки, создав XML-FO с помощью преобразования XSL из вашего SVG-файла. Это может противоречить другим вашим требованиям.

Вы можете посмотреть Отображение SVG с помощью XSLFO для получения дополнительной информации об этом методе.

person Alain BECKER    schedule 19.06.2012