XSLT - 将图像(和 pdf)转换为 base64
P粉529245050
P粉529245050 2024-01-16 16:01:19
0
1
434

我使用 Apache FOP 2.8 将 Apache FOP 中间格式 (IF) 文件转换为带有自行编写的 xslt 样式表的 HTML 文件

作为外部库,我目前只安装了 saxon12he。

问题#1(图像到base64)

在源 IF 文档中,有如下所示的图像 xml 元素:

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

将其转换为 HTML 并获得类似的输出会很容易

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

当使用如下模板时:

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

这里的问题是生成的 HTML-file 不能是“独立的”...意味着除了 HTML-file 之外还必须有 < code>files 目录,其中包含 Logo.png,以便 HTML-file 找到图像路径 files\Logo.png< /p>

但我想要实现的是 HTML 文件 是“独立的”。

有没有办法将 Logo.png 转换为 Base64 ,也许可以通过简单的函数调用,例如:

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

创建如下输出:

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

问题#2(pdf 到 base64)

另一个棘手的部分是,在中间格式中,xlink:href 也可以生成 .pdf 文件...

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

如果能够以与上面相同的方式将其转换为 Base64 图像,那就太好了。

或者也许还有另一种方法可以使 HTML 文档变得“独立”,但转换为 base64 是我迄今为止唯一的想法。

方法1(Saxon Java扩展函数)

我尝试按照本文档为 Saxon 12 HE 创建 Java 扩展函数

所以我实现了一个ExtensionFunctionDefinition

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

因为文档说:“实现这些扩展功能的类必须在配置中注册”,这可以“通过子类化 net.sf.saxon.Transform 或 net 来实现.sf.saxon.Query,重写方法 applyLocalOptions() 以便它对 config.registerExtensionFunction() 进行适当的调用;”我还添加了一个扩展 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);
    }
}

当我构建工件以获取 jar 文件时(我使用 IntelliJ 顺便说一句。)我只添加了“编译输出”,所以 jar 最后是 3kb .

然后我将 jar 放入 Apache FOP 的 saxon-he-12.2.jar 旁边的 lib 文件夹中,并添加 xmlns:ext="http://example.com/saxon-extension"xsl:stylesheet

但是当我现在打电话时

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

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

P粉529245050
P粉529245050

全部回复(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

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板