【问题标题】:How to print source XML into a PDF using XSL-FO?如何使用 XSL-FO 将源 XML 打印成 PDF?
【发布时间】:2012-02-27 12:32:13
【问题描述】:

美好的一天!我需要编写一个 xsl-fo 模板,但我无权访问源 XML。有没有办法将源 XML 打印到 PDF 中,以便我可以从 PDF 中复制它并粘贴到文件中?它应该与包含属性的源 xml 具有相同的结构。请问怎么办?先感谢您!沃杰科技

已编辑:我有一个 Web 界面,可以在其中粘贴模板并生成 PDF。但我不完全知道用作数据源的 XML 的结构是什么。所以我需要编写另一个模板来读取输入 XML(元素、属性、结构)并将其写入 PDF。然后我想复制 PDF 的内容并将其保存到 file.xml 中以便我可以研究它。

【问题讨论】:

  • 我以为你没有源 XML,那你想怎么打印呢?我不明白这个问题。

标签: xslt xslt-1.0 xsl-fo


【解决方案1】:

这是另一个大大简化的选项;只需打印整个 XML 的副本。

例子:

XML 输入

<doc attr="test">
  <a>Lorem ipsum dolor sit amet...</a>
  <b>
    <c>Lorem ipsum dolor sit amet...</c>
    <d>
      <e attr="another test"/>
      <f>Lorem ipsum dolor sit amet...</f>
    </d>
  </b>
</doc>

XSLT 1.0

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

  <xsl:template match="/">
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <fo:layout-master-set>
        <fo:simple-page-master master-name="my-page" page-width="8.5in" page-height="11in">
          <fo:region-body margin="1in" margin-top="1.5in" margin-bottom="1.5in"/>
        </fo:simple-page-master>
      </fo:layout-master-set>
      <fo:page-sequence master-reference="my-page">
        <fo:flow flow-name="xsl-region-body" font-family="monospace">
          <fo:block white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve">
            <xsl:text disable-output-escaping="yes">
              &lt;![CDATA[
            </xsl:text>
            <xsl:copy-of select="/*"/>
            <xsl:text disable-output-escaping="yes">
              ]]&gt;
            </xsl:text>
          </fo:block>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template>

</xsl:stylesheet>

XSL-FO 输出

<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
   <fo:layout-master-set>
      <fo:simple-page-master master-name="my-page" page-width="8.5in" page-height="11in">
         <fo:region-body margin="1in" margin-top="1.5in" margin-bottom="1.5in"/>
      </fo:simple-page-master>
   </fo:layout-master-set>
   <fo:page-sequence master-reference="my-page">
      <fo:flow flow-name="xsl-region-body" font-family="monospace">
         <fo:block white-space-collapse="false" white-space-treatment="preserve" linefeed-treatment="preserve">
              <![CDATA[
            <doc attr="test">
               <a>Lorem ipsum dolor sit amet...</a>
               <b>
                  <c>Lorem ipsum dolor sit amet...</c>
                  <d>
                     <e attr="another test"/>
                     <f>Lorem ipsum dolor sit amet...</f>
                  </d>
               </b>
            </doc>
              ]]>
            </fo:block>
      </fo:flow>
   </fo:page-sequence>
</fo:root>

PDF 输出 (Apache FOP)

【讨论】:

    【解决方案2】:

    Here你会发现一篇关于复制源 XML 的优秀文章。
    我刚刚将它包装成一个简单的 XSL-FO 存根,所以感谢原作者。这是完整的sn-p:

    <?xml version="1.0" encoding="iso-8859-1"?>
    
    <xsl:stylesheet version="1.0"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
         xmlns:fo="http://www.w3.org/1999/XSL/Format">
    
        <xsl:template match="/">
            <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
              <fo:layout-master-set>
                <fo:simple-page-master master-name="main">
                  <fo:region-body margin="1in"/>
                </fo:simple-page-master>
              </fo:layout-master-set>
    
              <fo:page-sequence master-reference="main">
                <fo:flow flow-name="xsl-region-body">
                  <fo:block text-align="left">
                    <xsl:apply-templates mode="escape"/>
                  </fo:block>
                </fo:flow>
              </fo:page-sequence>
            </fo:root>
        </xsl:template>
    
        <xsl:template match="*" mode="escape">
            <!-- Begin opening tag -->
            <xsl:text>&lt;</xsl:text>
            <xsl:value-of select="name()"/>
    
            <!-- Namespaces -->
            <xsl:for-each select="namespace::*">
                <xsl:text> xmlns</xsl:text>
                <xsl:if test="name() != ''">
                    <xsl:text>:</xsl:text>
                    <xsl:value-of select="name()"/>
                </xsl:if>
                <xsl:text>='</xsl:text>
                <xsl:call-template name="escape-xml">
                    <xsl:with-param name="text" select="."/>
                </xsl:call-template>
                <xsl:text>'</xsl:text>
            </xsl:for-each>
    
            <!-- Attributes -->
            <xsl:for-each select="@*">
                <xsl:text> </xsl:text>
                <xsl:value-of select="name()"/>
                <xsl:text>='</xsl:text>
                <xsl:call-template name="escape-xml">
                    <xsl:with-param name="text" select="."/>
                </xsl:call-template>
                <xsl:text>'</xsl:text>
            </xsl:for-each>
    
            <!-- End opening tag -->
            <xsl:text>&gt;</xsl:text>
    
            <!-- Content (child elements, text nodes, and PIs) -->
            <xsl:apply-templates select="node()" mode="escape" />
    
            <!-- Closing tag -->
            <xsl:text>&lt;/</xsl:text>
            <xsl:value-of select="name()"/>
            <xsl:text>&gt;</xsl:text>
        </xsl:template>
    
        <xsl:template match="text()" mode="escape">
            <xsl:call-template name="escape-xml">
                <xsl:with-param name="text" select="."/>
            </xsl:call-template>
        </xsl:template>
    
        <xsl:template match="processing-instruction()" mode="escape">
            <xsl:text>&lt;?</xsl:text>
            <xsl:value-of select="name()"/>
            <xsl:text> </xsl:text>
            <xsl:call-template name="escape-xml">
                <xsl:with-param name="text" select="."/>
            </xsl:call-template>
            <xsl:text>?&gt;</xsl:text>
        </xsl:template>
    
        <xsl:template name="escape-xml">
            <xsl:param name="text"/>
            <xsl:if test="$text != ''">
                <xsl:variable name="head" select="substring($text, 1, 1)"/>
                <xsl:variable name="tail" select="substring($text, 2)"/>
                <xsl:choose>
                    <xsl:when test="$head = '&amp;'">&amp;amp;</xsl:when>
                    <xsl:when test="$head = '&lt;'">&amp;lt;</xsl:when>
                    <xsl:when test="$head = '&gt;'">&amp;gt;</xsl:when>
                    <xsl:when test="$head = '&quot;'">&amp;quot;</xsl:when>
                    <xsl:when test="$head = &quot;&apos;&quot;">&amp;apos;</xsl:when>
                    <xsl:otherwise><xsl:value-of select="$head"/></xsl:otherwise>
                </xsl:choose>
                <xsl:call-template name="escape-xml">
                    <xsl:with-param name="text" select="$tail"/>
                </xsl:call-template>
            </xsl:if>
        </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多