我使用 Apache FOP 2.8 將 Apache FOP 中間格式 (IF) 檔案轉換為帶有自行編寫的 xslt 樣式表的 HTML 檔案
。
作為外部函式庫,我目前只安裝了 saxon12he。
在來源 IF 文件中,有如下所示的圖像 xml 元素:
<image xlink:href="files\Logo.png"/>
將其轉換為 HTML
並獲得類似的輸出會很容易
<img src="files\Logo.png"/>
當使用下列範本時:
<xsl:template match="image"> <xsl:variable name="file-path"><xsl:value-of select="@xlink:href"/></xsl:variable> <img src="{$file-path}"/> </xsl:template>
這裡的問題是產生的HTML-file
不能是「獨立的」...表示除了HTML-file
之外還必須有< code>files 目錄,其中包含Logo.png
,以便HTML-file
找到映像路徑files\Logo.png
< /p>
#但我想要實現的是 HTML 檔案
是「獨立的」。
有沒有辦法將 Logo.png
轉換為 Base64
,也許可以透過簡單的函數調用,例如:
<xsl:template match="image"> <xsl:variable name="file-path"><xsl:value-of select="@xlink:href"/></xsl:variable> <img src="to-base64($file-path)"/> </xsl:template>
建立如下輸出:
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...."/>
另一個棘手的部分是,在中間格式中,xlink:href
也可以產生 .pdf
檔案...
<image xlink:href="files\Table_1234.pdf"/>
如果能夠以與上面相同的方式將其轉換為 Base64 映像,那就太好了。
或者也許還有另一種方法可以使 HTML 文件變得“獨立”,但轉換為 base64 是我迄今為止唯一的想法。
我嘗試按照本文檔為 Saxon 12 HE 建立 Java 擴充函數
所以我實作了一個ExtensionFunctionDefinition
import net.sf.saxon.expr.XPathContext; import net.sf.saxon.lib.ExtensionFunctionCall; import net.sf.saxon.lib.ExtensionFunctionDefinition; import net.sf.saxon.om.Sequence; import net.sf.saxon.om.StructuredQName; import net.sf.saxon.trans.XPathException; import net.sf.saxon.value.SequenceType; import net.sf.saxon.value.StringValue; public class ImageToBase64 extends ExtensionFunctionDefinition { @Override public StructuredQName getFunctionQName() { return new StructuredQName("ext", "http://example.com/saxon-extension", "imageToBase64"); } @Override public SequenceType[] getArgumentTypes() { return new SequenceType[]{SequenceType.SINGLE_STRING}; } @Override public SequenceType getResultType(SequenceType[] suppliedArgumentTypes) { return SequenceType.SINGLE_STRING; } @Override public ExtensionFunctionCall makeCallExpression() { return new ExtensionFunctionCall() { @Override public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException { var filePath = ((StringValue)arguments[0]).getStringValue(); // open file and convert to base64 string var resultBase64 = "12345"; return StringValue.makeStringValue(resultBase64); } }; } }
因為文件說:“實現這些擴展功能的類別必須在配置中註冊”,這可以“透過子類化net.sf.saxon.Transform 或net 來實現.sf .saxon.Query,重寫方法applyLocalOptions() 以便它對config.registerExtensionFunction() 進行適當的調用;”我還添加了一個擴展net.sf.saxon.Transform< /代码>:
import net.sf.saxon.Transform; import net.sf.saxon.trans.CommandLineOptions; public class Configuration extends Transform { @Override protected void applyLocalOptions(CommandLineOptions options, net.sf.saxon.Configuration config) { config.registerExtensionFunction(new ImageToBase64()); super.applyLocalOptions(options, config); } }
當我建立工件以獲取jar
檔案時(我使用IntelliJ
順便說一句。)我只添加了“編譯輸出”,所以jar 最後是3kb .
然後我將 jar 放入 Apache FOP 的 saxon-he-12.2.jar
旁邊的 lib 資料夾中,並添加
xmlns:ext="http://example.com/saxon-extension"
到 xsl:stylesheet
。
但是當我現在打電話時
<xsl:value-of select="ext:imageToBase64('my/file/path')"/>
我收到錯誤net.sf.saxon.trans.XPathException:找不到名為Q{http://example.com/saxon-extension}imageToBase64() 的1 參數函數
< /p>
我在 @MartinHonnen 的幫助下完成了這個工作,他告訴我創建自己的擴充函數。
所以我建立了一個新的java程式(使用Java 8很重要)並且新增了兩個類別:
並根據此stackoverflow-entry另一個類別
MyTransformerFactory
:現在建立一個
jar
檔案並將其放入 Apache FOP 的lib
資料夾中。然後加入
set CUSTOMOPTS=-Djavax.xml.transform.TransformerFactory=ExtensionsPackage.MyTransformerFactory
到fop.bat
並將%CUSTOMOPTS%
加到:runFop
。將命名空間加入樣式表:
並這樣使用它:
如果現在透過控制台執行 fop.bat
xsl:value-of
將提供12345
。