Maison > Questions et réponses > le corps du texte
J'ai utilisé Apache FOP 2.8 pour convertir des fichiers au format intermédiaire (IF) Apache FOP en HTML 文件
avec une feuille de style xslt auto-écrite.
En tant que bibliothèque externe, je n'ai actuellement installé que saxon12he.
Dans le document source IF, il y a un élément image xml comme celui-ci :
<image xlink:href="files\Logo.png"/>
Il serait facile de le convertir en HTML
et d'obtenir un résultat similaire
<img src="files\Logo.png"/>
Lorsque vous utilisez le modèle suivant :
<xsl:template match="image"> <xsl:variable name="file-path"><xsl:value-of select="@xlink:href"/></xsl:variable> <img src="{$file-path}"/> </xsl:template>
La question ici est générée HTML-file
不能是“独立的”...意味着除了 HTML-file
之外还必须有 < code>files 目录,其中包含 Logo.png
,以便 HTML-file
找到图像路径 filesLogo.png
< /p>
Mais ce que je veux réaliser, c'est HTML 文件
être "indépendant".
Existe-t-il un moyen de convertir Logo.png
转换为 Base64
, peut-être via un simple appel de fonction comme :
<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>
Créez la sortie suivante :
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...."/>
L'autre partie délicate est que, dans le format intermédiaire, xlink:href
也可以生成 .pdf
les fichiers...
<image xlink:href="files\Table_1234.pdf"/>
Ce serait formidable si vous pouviez la convertir en image Base64 de la même manière que ci-dessus.
Ou peut-être existe-t-il une autre façon de rendre le document HTML "autonome", mais la conversion en base64 est la seule idée que j'ai jusqu'à présent.
J'ai essayé de créer une fonction d'extension Java pour Saxon 12 HE en suivant ce document
J'en ai donc implémenté unExtensionFunctionDefinition
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); } }; } }
Parce que la documentation dit : "Les classes implémentant ces fonctions étendues doivent être enregistrées dans la configuration " Cela peut être fait "en sous-classant net.sf.saxon.Transform ou net.sf.saxon.Query, en remplaçant la méthode applyLocalOptions( ) afin qu'il fasse l'appel approprié à config.registerExtensionFunction(); " J'ai également ajouté une extension 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); } }
Quand je construis l'artefact pour obtenir jar
文件时(我使用 IntelliJ
d'ailleurs. ) J'ai seulement ajouté "sortie de compilation", donc le pot a fini par faire 3 Ko .
Ensuite, j'ai mis le pot dans le dossier lib à côté d'Apache FOP saxon-he-12.2.jar
et j'ai ajouté
xmlns:ext="http://example.com/saxon-extension"
到 xsl:stylesheet
.
Mais quand j'appelle maintenant
<xsl:value-of select="ext:imageToBase64('my/file/path')"/>
J'ai eu une erreurnet.sf.saxon.trans.XPathException:找不到名为 Q{http://example.com/saxon-extension}imageToBase64() 的 1 参数函数
< /p>
P粉1285631402024-01-17 09:10:25
Je l'ai fait avec l'aide de @MartinHonnen qui m'a dit de créer ma propre fonction d'extension.
J'ai donc créé un nouveau programme java (important pour utiliser Java 8) et ajouté deux classes :
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); } }; } }
Et sur cette base stackoverflow-entry une autre classe 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); } }
Maintenant, créez un dossier jar
文件并将其放入 Apache FOP 的 lib
.
Puis ajoutez set CUSTOMOPTS=-Djavax.xml.transform.TransformerFactory=ExtensionsPackage.MyTransformerFactory
À fop.bat
并将 %CUSTOMOPTS%
添加到 :runFop
.
Ajouter un espace de noms à la feuille de style :
<xsl:stylesheet version="1.0" xmlns:ext="http://example.com/saxon-extension">
et utilisez-le comme ceci :
<xsl:value-of select="ext:imageToBase64('my/file/path')"/>
Si vous exécutez maintenant fop.bat via la console xsl:value-of
将提供 12345
.