java - Oxygen XML 编辑器和 Saxon 扩展函数
问题描述
我发帖寻求帮助,让我的 Saxon Extension 函数在 Oxygen XML Editor 中工作。我已经为函数定义、函数调用以及初始化程序类创建了 Java 类。我在一个 JAR 文件中有定义和函数调用,在一个单独的 JAR 文件中有初始化程序。我已将 JAR 文件和包含所有必需库的“lib”文件夹放在 XSL 所在的目录中:
我已在 Transformation Scenario 窗口的“Extensions”对话框中列出了它们:
我试图列出初始化程序:
当我在以下对话框中选择“选择”按钮,然后选择“检测”按钮时,它不会检测到类:
当我尝试转换时,我收到以下问题消息:
这是 ExtensionDefinition 类的代码:
import net.sf.saxon.lib.ExtensionFunctionCall;
import net.sf.saxon.lib.ExtensionFunctionDefinition;
import net.sf.saxon.om.StructuredQName;
import net.sf.saxon.value.SequenceType;
/**
*
* @author tfurst
*/
public class CreateXmlMapDefinition extends ExtensionFunctionDefinition{
@Override
public StructuredQName getFunctionQName() {
return new StructuredQName("rcmt", "http://rcmt.com/saxon-extension", "create-map");
}
@Override
public SequenceType[] getArgumentTypes() {
return new SequenceType[]{SequenceType.SINGLE_STRING};
}
@Override
public SequenceType getResultType(SequenceType[] sts) {
return SequenceType.ANY_SEQUENCE;
}
@Override
public ExtensionFunctionCall makeCallExpression() {
return new CreateXmlExtension();
}
}
这是函数调用的代码:
import com.rcmt.mapProcessor.ExcelMapProcessor;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import net.sf.saxon.expr.XPathContext;
import net.sf.saxon.lib.ExtensionFunctionCall;
import net.sf.saxon.om.DocumentInfo;
import net.sf.saxon.om.Sequence;
import net.sf.saxon.trans.XPathException;
import org.w3c.dom.Document;
public class CreateXmlExtension extends ExtensionFunctionCall{
@Override
public Sequence call(XPathContext xpc, Sequence[] args) throws XPathException
{
String excelPath = args[0].head().getStringValue();
DocumentInfo doc = getXml(xpc, excelPath);
return doc;
}
private DocumentInfo getXml(XPathContext context, String path)
{
DocumentInfo xml = null;
try
{
Document d = ExcelMapProcessor.makeXml(path);
xml = (DocumentInfo)context.getConfiguration().buildDocumentTree(makeSource(d));
}
catch (XPathException ex)
{
Logger.getLogger(CreateXmlExtension.class.getName()).log(Level.SEVERE, null, ex);
}
return xml;
}
private Source makeSource(Document doc)
{
Source result = null;
try
{
TransformerFactory transformerFactory = new net.sf.saxon.TransformerFactoryImpl();
Transformer trans = transformerFactory.newTransformer();
DOMSource src = new DOMSource(doc);
StreamResult res = new StreamResult(new ByteArrayOutputStream ());
trans.transform(src, res);
ByteArrayOutputStream so = (ByteArrayOutputStream)res.getOutputStream();
result = new StreamSource(new ByteArrayInputStream(so.toByteArray()));
so.close();
}
catch (TransformerException | IOException ex)
{
Logger.getLogger(CreateXmlExtension.class.getName()).log(Level.SEVERE, null, ex);
}
return result;
}
}
这是我的初始化程序的代码:
import javax.xml.transform.TransformerException;
import net.sf.saxon.Configuration;
import net.sf.saxon.lib.Initializer;
import net.sf.saxon.om.NamePool;
import org.expath.httpclient.saxon.SendRequestFunction;
import com.rcmt.map.CreateXmlMapDefinition;
/**
*
* @author tfurst
*/
public class SaxonExtInitializer implements Initializer{
@Override
public void initialize(Configuration config) throws TransformerException {
config.registerExtensionFunction(new CreateXmlMapDefinition());
SendRequestFunction expathHttpClient = new SendRequestFunction();
config.setNamePool(new NamePool());
expathHttpClient.setConfiguration(config);
config.registerExtensionFunction(expathHttpClient);
}
}
最后,XSL 中的用法:
解决方案
如果你有一个jar
包含你的扩展函数的ExtensionFunctionDefinition
和ExtensionFunctionCall
,那么,在那个jar
文件META-INF
夹中,创建一个名为的子文件夹,services
并在该文件夹内创建一个名为的文本文件net.sf.saxon.lib.ExtensionFunctionDefinition
,每行列出相关的类,例如CreateXmlMapDefinition
(前缀为其所在的任何命名空间)。
它看起来像这样:
然后在转换场景对话中提供该 jar 作为扩展。这样你就不需要任何初始化程序。我已经测试过 oXygen 22.1 和 Saxon 9.9。
推荐阅读
- python-3.x - NetworkX 似乎在 graphml 元素声明中删除了信息——有没有办法恢复它?
- c# - Stephen Cleary 关于异步的新日志记录模式问题
- ios - API_DEPRECATED_WITH_REPLACEMENT 到底是什么意思?
- javascript - 如何通过 Javascript 设置 xlsx 文件的计算模式?
- python - 减去两个列表,但值在 Python 中没有相加
- javascript - 尝试连接 mongoDB 时,打字稿发布未定义
- facebook-graph-api - 无法使用 Graph API v10.0 检索 Facebook 广告报告
- java - Java中文档的页数
- postgresql - 通用表/连接表 一个好主意?
- reactjs - 使用 react-table v7 创建嵌套表