cari

Rumah  >  Soal Jawab  >  teks badan

XSLT - Tukar imej (dan pdf) kepada base64

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粉529245050P粉529245050315 hari yang lalu467

membalas semua(1)saya akan balas

  • P粉128563140

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

    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.

    balas
    0
  • Batalbalas