2012-02-27 31 views
3

美好的一天!我需要編寫一個xsl-fo模板,但我無法訪問源XML。有沒有辦法如何將源XML打印到PDF中,以便我可以從PDF中複製它並粘貼到文件中?它應該具有與包含屬性的源xml相同的結構。請問怎麼做?先謝謝你! Vojtech如何使用XSL-FO將源XML打印到PDF中?

編輯:我有一個Web界面,我可以粘貼我的模板並生成PDF。但我不完全知道用作數據源的XML的結構是什麼。所以我需要編寫另一個模板來讀取輸入XML(元素,屬性,結構)並將其寫入PDF。我想複製PDF的內容,然後將其保存到file.xml中,以便我可以研究它。

+0

我還以爲你沒有源XML,你要如何打印它呢?我不明白這個問題。 – mindandmedia 2012-02-27 12:35:35

回答

3

這裏是一個被大大簡化另一種選擇;只需打印整個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)

enter image description here

2

Here你會發現一篇關於複製源XML的優秀文章。
我剛把它包裝成一個簡單的XSL-FO存根,所以完全感謝原作者。下面是完整的片段:

<?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>