直接使用Saxon API使用系统功能

问题描述

我想使用Saxon API将用户提供的JSON文档转换为其XML表示形式,然后将其用作XSLT转换的输入。

有没有一种方法可以执行此转换而无需实际使用XQuery / XPath?

我尝试使用JsonToXMLFn来模仿json-to-xml XPath函数,而没有实际编写XSLT或XQuery,但是我很快遇到了问题,因为(逻辑上)它需要一个XPathContext,而且我没有找到使用公共API生成内容的简便方法

我目前使用

XQueryExecutable exec = processor.newXQueryCompiler().compile("json-to-xml(.)");
XQueryEvaluator eval = exec.load();
eval.setContextItem(new XdmAtomicValue(jsonString));
XdmDestination destination = new XdmDestination();
eval.run(destination);
return destination.getXdmNode();

哪个工作正常。但是我想知道是否有一种方法无需解析和编译XQuery表达式。

解决方法

也许XdmFunctionItem.getSystemFunction(processor,new QName("http://www.w3.org/2005/xpath-functions","json-to-xml"),1).call(processor,new XdmAtomicValue(jsonString))可以工作,但在HE 10.2中,它会抛出异常“动态功能需要Saxon-PE或更高版本。”

我不确定在XPath表达式中HE 10是否允许动态函数调用;是否仍然打算这样做? https://saxonica.plan.io/projects/saxon/repository/he/revisions/master/entry/latest10/hej/net/sf/saxon/s9api/XdmFunctionItem.java#L69文档说:

 * Get a system function. This can be any function defined in XPath 3.1 functions and operators,* including functions in the math,map,and array namespaces. It can also be a Saxon extension
 * function,provided a licensed Processor is used.
 * @return the requested function,or null if there is no such function. Note that some functions
 * (those with particular context dependencies) may be unsuitable for dynamic calling.
 * @throws SaxonApiException if dynamic function calls are not permitted by this Saxon Configuration

https://saxonica.plan.io/projects/saxon/repository/he/revisions/master/entry/latest10/hej/net/sf/saxon/Configuration.java#L1505会抛出

/**
 * Get a system function. This can be any function defined in XPath 3.1 functions and operators,provided a licensed Processor is used.
 *
 * @param name  the name of the required function
 * @param arity the arity of the required function
 * @return the requested function,or null if there is no such function. Note that some functions
 * (those with particular context dependencies) may be unsuitable for dynamic calling.
 * @throws XPathException if dynamic function calls are not permitted by this Saxon Configuration
 */
public Function getSystemFunction(StructuredQName name,int arity) throws XPathException {
    throw new XPathException("Dynamic functions require Saxon-PE or higher");
}

因此,除非您使用PE或EE,否则这似乎还不受支持。使用补丁https://saxonica.plan.io/projects/saxon/repository/he/revisions/e5cb4f89b97633000285987b48638a53c6a81b51或在以后的Saxon HE 10或更高版本中将起作用。

在最新的10.3版本中,现在可以使用:

    String jsonString = "{ \"number\" : 3.14,\"boolean\": true,\"string\": \"whatever\",\"data\" : [1,2,3,4] }";
    
    XdmValue jsonXml = XdmFunctionItem.getSystemFunction(processor,new XdmAtomicValue(jsonString));
    
    System.out.println(jsonXml);

给予

<map xmlns="http://www.w3.org/2005/xpath-functions">
   <number key="number">3.14</number>
   <boolean key="boolean">true</boolean>
   <string key="string">whatever</string>
   <array key="data">
      <number>1</number>
      <number>2</number>
      <number>3</number>
      <number>4</number>
   </array>
</map>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...