Heim > Fragen und Antworten > Hauptteil
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.
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...."/>
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.
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
und hinzugefügt
saxon-he-12.2.jar
. xmlns:ext="http://example.com/saxon-extension"
到 xsl:stylesheet
<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粉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.MyTransformerFactory
到 fop.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
。