关于XSLT的初学者问题

Kev*_*vin 3 xslt xsl-fo saxon

我刚开始学习XSLT,现在我正在学习它的一些在线教程,现在我只有一个简单的问题:

假设我们有一个原始的xml文件,我们是否需要编写一个XSLT样式表来处理它,或者我们只是简单地将xml文件传递给某些软件,如Stylus Studio(Saxon Engine),然后它会自动执行所有这些操作我们?

很抱歉澄清错误.我需要将此.svg文件转换为pdf,我刚刚开始开发,所以对第一步真的很困惑.另外,我想知道,如果我最初的输入是一个.svg文件,在开始使用XSLT之前,是否必须将其显式转换为.xml?

提前致谢!

Dan*_*ley 8

很抱歉澄清错误.我需要将此.svg文件转换为pdf,我刚刚开始开发,所以对第一步真的很困惑.另外,我想知道,如果我最初的输入是一个.svg文件,在开始使用XSLT之前,是否必须将其显式转换为.xml?

SVG文件 SVG名称空间中的XML文件.是否需要转换XML取决于您将如何使用它.如果您打算使用像Inkscape(SVG编辑器)这样的批量打印,那么您就不会.

如果你打算使用类似XSL-FO的东西,你会的.@Zoltan Hamori的回答有点误导.您可以使用saxon执行XSLT转换(创建XSL-FO),但是您仍然需要XSL-FO处理器来从XSL-FO创建PDF.

Zoltan提到FOP(Apache格式化对象处理器),但他听起来像FOP和XSL-FO是一样的; 他们不是.他的代码示例是一个XSL-FO表(fo命名空间中的XML ).您需要一个处理器,如FOP,RenderX,Antenna House等,才能从XSL-FO创建PDF.

基本上你需要的是:

  1. XML输入(这将是您的SVG文件)
  2. XSLT转换创建XSL-FO.
  3. XSL-FO处理器从XSL-FO创建PDF

在学习XSLT的同时学习XSL-FO会很困难,但我将向您展示两种在PDF中输出SVG的方法.

第一种方法是使用引用SVG文件fo:external-graphic.

第二种方法是使用将SVG XML直接嵌入到XSL-FO中fo:instream-foreign-object.

由于XML输入是SVG XML,我将使用第二个选项.但是,我不确定这会对处理时间产生什么影响,哪种方式会更有效.

我在下面展示了一个例子.由于我展示了两种输出SVG的方法,因此这将创建一个2页的PDF.每个页面都有SVG图形.

笔记

  • 为了测试,我使用了Inkscape附带的示例SVG文件.(我从XSL-FO输出中删除了大部分SVG XML,因为它非常大.)
  • 对于我的XSLT处理器,我使用了Saxon-HE 9.2.0.6.
  • 对于我的FO处理器,我使用了Apache FOP版本0.95(虽然我更喜欢RenderX).

  • Saxon-HE和Apache FOP都是免费的.
  • 如果你给我你的电子邮件,我可以发送我使用的SVG文件以及完整的XSL-FO输出.我也可以发给你创建的PDF.

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!-- 
    This is an "identity" template.
    It copies whatever node from input to the output without changing it. 
    Learn it. Use it. Love it. -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/">
    <fo:root>
      <fo:layout-master-set>
        <fo:simple-page-master master-name="my-page">
          <fo:region-body/>
        </fo:simple-page-master>
      </fo:layout-master-set>
      <fo:page-sequence master-reference="my-page">
        <fo:flow flow-name="xsl-region-body">
          <fo:block>
            <!-- This is the first way to output an SVG; by referencing the graphic. -->
            <fo:external-graphic src="test.svg"/>
            <!-- This is the second way to output an SVG; by outputting the SVG XML directly. -->
            <fo:instream-foreign-object>
              <xsl:apply-templates/>
            </fo:instream-foreign-object>
          </fo:block>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template>

</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

XSL-FO(由Saxon从SVG输入和XSL样式表创建)

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:svg="http://www.w3.org/2000/svg">
   <fo:layout-master-set>
      <fo:simple-page-master master-name="my-page">
         <fo:region-body/>
      </fo:simple-page-master>
   </fo:layout-master-set>
   <fo:page-sequence master-reference="my-page">
      <fo:flow flow-name="xsl-region-body">
         <fo:block>
            <fo:external-graphic src="test.svg"/>
            <fo:instream-foreign-object>
              <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
                    version="1.1"
                    width="595.99438"
                    height="491.50516"
                    id="svg2675">
                <!-- CONTENT REMOVED FOR STACKOVERFLOW.COM EXAMPLE -->
              </svg>
            </fo:instream-foreign-object>
         </fo:block>
      </fo:flow>
   </fo:page-sequence>
</fo:root>
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.