Saxon-HE 集成扩展功能 |如何以及在哪里?

Posted

技术标签:

【中文标题】Saxon-HE 集成扩展功能 |如何以及在哪里?【英文标题】:Saxon-HE Integrated Extension Functions | how and where? 【发布时间】:2016-01-28 06:56:29 【问题描述】:

虽然写 Saxon Integrated Extension Functions 对我来说很清楚。

我有红色:

http://www.saxonica.com/html/documentation/extensibility/integratedfunctions/ http://www.saxonica.com/html/documentation/extensibility/integratedfunctions/ext-simple-J.html

我很难找到如何真正让它们工作的信息。

问:文件放在哪里,我必须编译什么,我必须编辑 saxon 配置吗?基本上,除了向 s9api 处理器注册扩展功能之外,我还需要做什么才能使其正常工作。

【问题讨论】:

saxonica.com/html/documentation/extensibility/… 中的示例不适合您吗?我将该代码粘贴到使用 NetBeans 创建的 Java 应用程序模板中,在该模板中我添加了 saxon9he.jar 作为库,让 IDE 修复使用的类和接口的导入部分(我必须修复 QName 的一个导入作为选择的导入是针对不同的类),让IDE在main方法中添加throws SaxonApiException,代码编译运行并添加System.out.println(result);输出结果。 或者你想实现你的扩展功能并在命令行运行net.sf.saxon.Transform时使用它们? 1) 感谢马丁的快速回复。同时我必须弄清楚下载SaxonHE的未编译版本这样一个基本的事情,正如你提到的,我试图在Eclipse中使用这个源代码创建项目。它在那里,但老实说,我不知道从哪里开始。所以我的问题更多是关于使用SaxonHE 源代码设置Java 环境。 2) 我希望在xsl template 中使用我的扩展功能,例如<xsl:value-of select="myfunction( )"/> 在 Eclipse 或其他 IDE 中编写 Java 应用程序不需要 Saxon 的源代码,带有二进制类的 saxon9he.jar 就足够了。至于入门,我认为如果您知道要使用 Eclipse,那么也许适当地标记您的问题并寻求帮助在 IDE 中设置应用程序会给您一个更好的答案。另一方面,我猜有一些教程可以解释如何开始使用您最喜欢的 IDE 来使用外部库编写应用程序。 好吧,尽管你没有提供任何具体的例子,但你让我开始了。我会尽快与spring 合作发布答案。 【参考方案1】:

TestMain.java - 一些可以访问转换工厂的 java 文件

import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import net.sf.saxon.TransformerFactoryImpl;
import net.sf.saxon.s9api.ExtensionFunction;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.jaxp.SaxonTransformerFactory;
import location.to.test.java.file.Test;

public class TestMain 
    public static void main(String[] args) throws IOException, URISyntaxException, TransformerException 

        TransformerFactory factory = TransformerFactory.newInstance();

        // Grab the handle of Transformer factory and cast it to TransformerFactoryImpl
        TransformerFactoryImpl tFactoryImpl = (TransformerFactoryImpl) factory;

        // Get the currently used processor
        net.sf.saxon.Configuration saxonConfig = tFactoryImpl.getConfiguration();
        Processor processor = (Processor) saxonConfig.getProcessor();

        // Here extension happens, test comes from class Test -> Test.java
        ExtensionFunction test = new Test();
        processor.registerExtensionFunction(test);

        Source xslt = new StreamSource(new File("test.xsl"));
        Transformer transformer = factory.newTransformer(xslt);

        Source text = new StreamSource(new File("input.xml"));
        transformer.transform(text, new StreamResult(new File("result.xml")));
    

Test.java - 实际的扩展函数逻辑

import net.sf.saxon.s9api.ExtensionFunction;
import net.sf.saxon.s9api.ItemType;
import net.sf.saxon.s9api.OccurrenceIndicator;
import net.sf.saxon.s9api.QName;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.SequenceType;
import net.sf.saxon.s9api.XdmAtomicValue;
import net.sf.saxon.s9api.XdmValue;

public class Test implements ExtensionFunction 

    @Override
    public QName getName() 
        return new QName("http://some.namespace.com", "test");
    

    @Override
    public SequenceType getResultType() 
        return SequenceType.makeSequenceType(ItemType.STRING, OccurrenceIndicator.ONE);
    

    @Override
    public net.sf.saxon.s9api.SequenceType[] getArgumentTypes() 
        return new SequenceType[] ;
    

    @Override
    public XdmValue call(XdmValue[] arguments) throws SaxonApiException 
        String result = "Saxon is being extended correctly.";
        return new XdmAtomicValue(result);
    


test.xsl - 测试 xsl。文件

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:ext="http://some.namespace.com">
    <xsl:output indent="yes"/>

    <xsl:template match="/">
        <root>
                <xsl:value-of select="ext:test()" />
        </root>
     </xsl:template>
</xsl:stylesheet>

result.xml - 整个过程的结果

<?xml version="1.0" encoding="UTF-8"?>
<root>Saxon is being extended correctly.</root>

请注意 .java 和 .xsl 文件中使用的命名空间必须相同,在 QName 中声明

【讨论】:

这段代码给了我以下异常:net.sf.saxon.TransformerFactoryImpl cannot be cast to net.sf.saxon.s9api.Processor at Processor processor = (Processor) saxonConfig.getProcessor();跨度> 你能确保你的导入完美无瑕吗? 如果我从命令行使用 saxon 应该怎么办?我想我将包含扩展函数的类添加到类路径中。但是如何实现等效: ExtensionFunction test = new Test(); processor.registerExtensionFunction(test); 好吧,你应该问一个不同的问题,提供更多数据并将其链接到此处:) 也许我们可以直接解决问题 您的解决方案对我不起作用。我不得不扩展 ExtensionFunctionDefinition,而不是实现 ExtensionFunction,这解决了问题。

以上是关于Saxon-HE 集成扩展功能 |如何以及在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

Saxon-HE Java 扩展函数(问题配置)

如何在 Saxon-HE 中获得 EXSLT 支持?

Grails - 在哪里放置测试文件以及如何加载它们

Nginx 集成 lua 模块扩展功能,以及遇到的一些问题

如何在 .NET 中使用 Saxon-HE 9.8 使用 XSLT 3.0

Android:在哪里以及如何自动刷新列表视图(我有刷新功能)