搜尋

首頁  >  問答  >  主體

XSLT - 將影像(和 pdf)轉換為 base64

我使用 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粉529245050P粉529245050397 天前632

全部回覆(1)我來回復

  • P粉128563140

    P粉1285631402024-01-17 09:10:25

    我在 @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

    回覆
    0
  • 取消回覆