suchen

Heim  >  Fragen und Antworten  >  Hauptteil

XSLT – Bilder (und PDF) in Base64 konvertieren

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粉529245050P粉529245050315 Tage vor466

Antworte allen(1)Ich werde antworten

  • 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

    Antwort
    0
  • StornierenAntwort