XSLT - Tukar imej (dan pdf) kepada base64
P粉529245050
P粉529245050 2024-01-16 16:01:19
0
1
514

Saya menggunakan Apache FOP 2.8 untuk menukar fail format perantaraan (IF) Apache FOP kepada HTML 文件 dengan helaian gaya xslt yang ditulis sendiri.

Sebagai perpustakaan luaran, pada masa ini saya hanya memasang saxon12he.

Masalah #1 (Imej ke base64)

Dalam dokumen sumber IF, terdapat elemen xml imej seperti ini:

<image xlink:href="files\Logo.png"/>

Adalah mudah untuk menukarnya kepada HTML dan mendapatkan output yang serupa

<img src="files\Logo.png"/>

Apabila menggunakan templat berikut:

<xsl:template match="image">
    <xsl:variable name="file-path"><xsl:value-of select="@xlink:href"/></xsl:variable>
    <img src="{$file-path}"/>
</xsl:template>

Persoalan di sini dijana HTML-file 不能是“独立的”...意味着除了 HTML-file 之外还必须有 < code>files 目录,其中包含 Logo.png,以便 HTML-file 找到图像路径 filesLogo.png< /p>

Tetapi apa yang saya ingin capai ialah HTML 文件 "berdikari".

Adakah cara untuk menukar Logo.png 转换为 Base64 , mungkin melalui panggilan fungsi mudah seperti:

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

Buat output berikut:

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...."/>

Soalan #2 (pdf hingga base64)

Bahagian rumit yang lain ialah, dalam format pertengahan, xlink:href 也可以生成 .pdf fail...

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

Alangkah bagus jika anda boleh menukarnya kepada imej Base64 dengan cara yang sama seperti di atas.

Atau mungkin ada cara lain untuk menjadikan dokumen HTML "berdikari", tetapi menukar kepada base64 adalah satu-satunya idea yang saya ada setakat ini.

Kaedah 1 (fungsi sambungan Java Saxon)

Saya cuba mencipta fungsi sambungan Java untuk Saxon 12 HE mengikuti dokumen ini

Jadi saya melaksanakan satuExtensionFunctionDefinition

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);
            }
        };
    }
}

Oleh kerana dokumentasi mengatakan: "Kelas yang melaksanakan fungsi lanjutan ini mesti didaftarkan dalam konfigurasi " Ini boleh dilakukan "dengan mensubkelaskan net.sf.saxon.Transform atau net.sf.saxon.Query, mengatasi kaedah applyLocalOptions( ) supaya ia membuat panggilan yang sesuai untuk config.registerExtensionFunction(); " Saya juga menambah sambungan 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);
    }
}

Apabila saya membina artifak untuk mendapatkan jar 文件时(我使用 IntelliJ btw. ) Saya hanya menambah "output compile" jadi balang akhirnya menjadi 3kb .

Kemudian saya meletakkan balang ke dalam folder lib di sebelah Apache FOP's saxon-he-12.2.jar dan menambah xmlns:ext="http://example.com/saxon-extension"xsl:stylesheet.

Tapi bila saya call sekarang

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

Saya mendapat ralatnet.sf.saxon.trans.XPathException:找不到名为 Q{http://example.com/saxon-extension}imageToBase64() 的 1 参数函数< /p>

P粉529245050
P粉529245050

membalas semua(1)
P粉128563140

Saya melakukan ini dengan bantuan @MartinHonnen yang memberitahu saya untuk mencipta fungsi sambungan saya sendiri.

Jadi saya mencipta program java baharu (penting untuk menggunakan Java 8) dan menambah dua kelas:

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);
            }
        };
    }
}

Dan berdasarkan ini stackoverflow-entry kelas lain 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);
    }
}

Sekarang bina folder jar 文件并将其放入 Apache FOP 的 lib.

Kemudian tambah set CUSTOMOPTS=-Djavax.xml.transform.TransformerFactory=ExtensionsPackage.MyTransformerFactory Kepada fop.bat 并将 %CUSTOMOPTS% 添加到 :runFop.

Tambah ruang nama pada helaian gaya:

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

dan gunakannya seperti ini:

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

Jika anda kini melaksanakan fop.bat melalui konsol xsl:value-of 将提供 12345.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan