XSLT - 將影像(和 pdf)轉換為 base64
P粉529245050
P粉529245050 2024-01-16 16:01:19
0
1
502

我使用 Apache FOP 2.8 將 Apache FOP 中間格式 (IF) 檔案轉換為帶有自行編寫的 xslt 樣式表的 HTML 檔案

作為外部函式庫,我目前只安裝了 saxon12he。

問題#1(圖片到base64)

在來源 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...."/>

問題#2(pdf 到 base64)

另一個棘手的部分是,在中間格式中,xlink:href 也可以產生 .pdf 檔案...

<image xlink:href="files\Table_1234.pdf"/>

如果能夠以與上面相同的方式將其轉換為 Base64 映像,那就太好了。

或者也許還有另一種方法可以使 HTML 文件變得“獨立”,但轉換為 base64 是我迄今為止唯一的想法。

方法1(Saxon Java擴充函數)

我嘗試按照本文檔為 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>

P粉529245050
P粉529245050

全部回覆(1)
P粉128563140

我在 @MartinHonnen 的幫助下完成了這個工作,他告訴我創建自己的擴充函數。

所以我建立了一個新的java程式(使用Java 8很重要)並且新增了兩個類別:

package ExtensionsPackage;

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 {
                String filePath = ((StringValue)arguments[0]).getStringValue();
                // open file and convert to base64 string
                String resultBase64 = "12345";
                return StringValue.makeStringValue(resultBase64);
            }
        };
    }
}

並根據此stackoverflow-entry另一個類別MyTransformerFactory

package ExtensionsPackage;

import net.sf.saxon.Configuration;
import net.sf.saxon.TransformerFactoryImpl;
import net.sf.saxon.lib.ExtensionFunctionDefinition;

public class MyTransformerFactory extends TransformerFactoryImpl {
    public MyTransformerFactory() {
        super();
        ExtensionFunctionDefinition imageToBase64Function = new ImageToBase64();
        this.getProcessor().registerExtensionFunction(imageToBase64Function);
    }

    public MyTransformerFactory(Configuration config) {
        super(config);
        ExtensionFunctionDefinition imageToBase64Function = new ImageToBase64();
        this.getProcessor().registerExtensionFunction(imageToBase64Function);
    }
}

現在建立一個 jar 檔案並將其放入 Apache FOP 的 lib 資料夾中。

然後加入set CUSTOMOPTS=-Djavax.xml.transform.TransformerFactory=ExtensionsPackage.MyTransformerFactoryfop.bat 並將 %CUSTOMOPTS% 加到 :runFop

將命名空間加入樣式表:

<xsl:stylesheet version="1.0" 
    xmlns:ext="http://example.com/saxon-extension">

並這樣使用它:

<xsl:value-of select="ext:imageToBase64('my/file/path')"/>

如果現在透過控制台執行 fop.bat xsl:value-of 將提供 12345

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板