簡體   English   中英

Java中的Apache FOP發生XSL錯誤

[英]XSL Error with Apache FOP in Java

我花了一整天的時間來尋找該錯誤的解決方案,其他任何話題都沒有真正解決這個問題,更不用說解決它了。 因此,如果這是一個重復的問題,我事先表示歉意。

我們有一個應用程序,允許用戶將圖像保存到后端數據存儲中並從中檢索圖像。 我們還允許它們在圖像中包含元數據(稱為注釋)。 對於TIFF圖像,當用戶檢索圖像時,我們還將檢索注釋(以XML格式)。 我們使用Apache FOP將文本格式化為表格,然后將其呈現為PNG文件並與TIFF一起顯示。

直到最近一直在工作。 現在,我在調用將XML轉換為PNG文件時看到以下錯誤:

SXCH0003:org.apache.fop.fo.ValidationException:“ fo:table-body”缺少子元素。 必需的內容模型:標記<XSL file:line#>“ fo:table-body”缺少子元素。 必需的內容模型:標記*(表行+ |表單元格+)(請參見位置<行號>)

最初,我們認為這是一個數據問題,由源XML中的空元素/屬性引起。 我添加了代碼,這些代碼將在所有缺少XML的地方將占位符值強制插入XML。 當那不能解決問題時,可以相信XSL(我沒有寫過)很可能是問題的根源。

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" 
   xmlns:fo="http://www.w3.org/1999/XSL/Format" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:myns="http://xmlapp.fm.net/ns/app/service">

   <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-top="1cm" margin-bottom="1cm" />
               <fo:region-before extent="0.5cm" />
               <fo:region-after region-name="xsl-region-after" display-align="before" extent="2.0cm"/>
            </fo:simple-page-master>
         </fo:layout-master-set>

          <fo:page-sequence master-reference="main">
            <fo:static-content flow-name="xsl-region-before">
               <fo:block>Page title text</fo:block>
            </fo:static-content>
            <fo:static-content flow-name="xsl-region-after" >
               <fo:block-container left="500pt" top="28pt" width="220mm" position="absolute">
                  <fo:block font-size="16"><xsl:value-of select="//myns:cust" /> : <xsl:value-of select="//myns:docId" /></fo:block>
               </fo:block-container>
            </fo:static-content>
            <fo:flow flow-name="xsl-region-body" >
               <xsl:call-template name="annotationsTable" />
            </fo:flow>
         </fo:page-sequence>
       </fo:root>
   </xsl:template>

   <xsl:template name="annotationsTable">
      <fo:table table-layout="fixed">
         <fo:table-header>
            <fo:table-row>
               <fo:table-cell><fo:block> Annotation </fo:block></fo:table-cell>
               <fo:table-cell><fo:block> UserName </fo:block></fo:table-cell>
               <fo:table-cell><fo:block> UserID </fo:block></fo:table-cell>
               <fo:table-cell><fo:block> Date </fo:block></fo:table-cell>
            </fo:table-row>
         </fo:table-header>
         <fo:table-body>
            <xsl:apply-templates select="//myns:annotation" />
         </fo:table-body>
      </fo:table>
   </xsl:template>

    <xsl:template match="myns:annotation">
      <fo:table-row>
         <fo:table-cell>
            <fo:block>
               <xsl:value-of select="./myns:text" />
            </fo:block>
         </fo:table-cell>
         <fo:table-cell>
            <fo:block>
               <xsl:value-of select="./@createdByName"/>
            </fo:block>
         </fo:table-cell>
         <fo:table-cell>
            <fo:block>
               <xsl:value-of select="./@createdByUserID" />
            </fo:block>
         </fo:table-cell>
         <fo:table-cell>
            <fo:block>
               <xsl:value-of select="./@systemDate" />
            </fo:block>
         </fo:table-cell>
      </fo:table-row>
   </xsl:template>

</xsl:stylesheet>

我們嘗試轉換的XML格式為:

<annotation createdByName="Frank" createdByUserID="X1234" systemDate="2014-04-14">
   <text>this is the text of an annotation</text>
</annotation>

我知道我做錯了。 問題是我對XSL的了解不足。 有人可以建議嗎?

謝謝。

您的代碼無法正常工作,因為XPath表達式未選擇no-namespace源來嘗試匹配元素http://xmlapp.fm.net/ns/app/service命名空間。 解決方案是在源中將名稱空間聲明為默認名稱(添加xmlns屬性),或者在XSLT中修復表達式,使它們與no-namespace匹配。

1)要解決該問題,請更改XSLT,從XPath元素中刪除myns:前綴。

annotationsTable模板的myns:annotation中:

<xsl:template name="annotationsTable">
    ...
        <fo:table-body>
            <xsl:apply-templates select="annotation" />
        </fo:table-body>
    </fo:table>
</xsl:template>

並來自myns:annotation myns:annotation模板中的myns:annotationmyns:text元素:

<xsl:template match="annotation">
    <fo:table-row>
        <fo:table-cell>
            <fo:block>
                <xsl:value-of select="text" />
            </fo:block>
        </fo:table-cell>
        <fo:table-cell>
            <fo:block>
                <xsl:value-of select="@createdByName"/>
            </fo:block>
        </fo:table-cell>
        <fo:table-cell>
            <fo:block>
                <xsl:value-of select="@createdByUserID" />
            </fo:block>
        </fo:table-cell>
        <fo:table-cell>
            <fo:block>
                <xsl:value-of select="@systemDate" />
            </fo:block>
        </fo:table-cell>
    </fo:table-row>
</xsl:template>

現在,它應該生成表主體內容。

2)如果首先存在名稱空間前綴,則可能是您的源最初具有名稱空間。 在這種情況下,您將XSLT保留為原樣 ,並編輯源代碼,並聲明一個默認名稱空間:

<annotation xmlns="http://xmlapp.fm.net/ns/app/service" 
            createdByName="Frank" createdByUserID="X1234" systemDate="2014-04-14">
    <text>this is the text of an annotation</text>
</annotation>

現在,所有元素都屬於“ http://xmlapp.fm.net/ns/app/service ”命名空間,並且您的XSLT將該命名空間映射到前綴( myns ),因此您可以在XPath中選擇源樹的節點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM