XSLT – Bilder (und PDF) in Base64 konvertieren
P粉529245050
P粉529245050 2024-01-16 16:01:19
0
1
444

Ich habe Apache FOP 2.8 verwendet, um Apache FOP Intermediate Format (IF)-Dateien mit einem selbst geschriebenen XSLT-Stylesheet in HTML 文件 zu konvertieren.

Als externe Bibliothek habe ich derzeit nur saxon12he installiert.

Problem Nr. 1 (Bild zu Base64)

Im Quell-IF-Dokument gibt es ein Bild-XML-Element wie dieses:

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

Es wäre einfach, es in HTML umzuwandeln und eine ähnliche Ausgabe zu erhalten

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

Bei Verwendung der folgenden Vorlage:

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

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

Aber was ich erreichen möchte, ist HTML 文件 „unabhängig“ zu sein.

Gibt es eine Möglichkeit, Logo.png 转换为 Base64 zu konvertieren, vielleicht durch einen einfachen Funktionsaufruf wie:

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

Erstellen Sie die folgende Ausgabe:

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

Frage Nr. 2 (PDF zu Base64)

Der andere schwierige Teil ist, dass im Zwischenformat xlink:href 也可以生成 .pdf die Dateien...

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

Es wäre großartig, wenn Sie es auf die gleiche Weise wie oben in ein Base64-Image konvertieren könnten.

Oder vielleicht gibt es eine andere Möglichkeit, das HTML-Dokument „eigenständig“ zu machen, aber die Konvertierung in Base64 ist die einzige Idee, die ich bisher habe.

Methode 1 (Sächsische Java-Erweiterungsfunktion)

Ich habe versucht, nach diesem Dokument eine Java-Erweiterungsfunktion für Saxon 12 HE zu erstellen

Also habe ich eines implementiertExtensionFunctionDefinition

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

Weil in der Dokumentation steht: „Klassen, die diese erweiterten Funktionen implementieren, müssen in der Konfiguration registriert werden “ Dies kann „durch Unterklassen von net.sf.saxon.Transform oder net.sf.saxon.Query und Überschreiben der Methode applyLocalOptions( ), damit config.registerExtensionFunction(); " aufgerufen wird, habe ich auch eine Erweiterung net.sf.saxon.Transform hinzugefügt: < /代码>

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

Wenn ich das Artefakt baue, um

übrigens zu bekommen. ) Ich habe nur „Ausgabe kompilieren“ hinzugefügt, sodass das JAR am Ende 3 KB groß war .jar 文件时(我使用 IntelliJ

Dann habe ich das JAR in den lib-Ordner neben Apache FOPs gelegt

und hinzugefügt saxon-he-12.2.jar. xmlns:ext="http://example.com/saxon-extension"xsl:stylesheet

Aber wenn ich jetzt anrufe

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

Ich habe einen Fehler erhalten

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

P粉529245050
P粉529245050

Antworte allen(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

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage