javascript xslt 中的函数与 saxon 9 HE
javascript functions in xslt with saxon 9 HE
当我 运行 我的 xsl 样式表时,我需要知道是否存在某些文件。因为 xslt 没有本地方法来测试文件是否存在 (ASFAIK),所以我想用 javascript 来做这个。通常我使用 saxon 9 HE,但一些同事告诉我 java脚本函数不受 HE 版本的支持。有没有办法用 saxon 9 HE 执行 java 脚本函数?
我试过这个例子:How to include javaScript file in xslt,但是氧气给了我这个错误:"Cannot find a matching 1-argument function named".
您可以使用 XPath 函数 doc-available
https://www.w3.org/TR/xpath-functions/#func-doc-available and unparsed-text-available
https://www.w3.org/TR/xpath-functions/#func-unparsed-text-available 检查是否存在 XML 文档或 non-XML 文本文档。
不支持在 Saxon 9 中使用 Javascript(并且简单的 ECMAScript/Javascript 引擎通常不包含任何文件 IO 功能)但是有一个称为集成扩展功能的功能 http://saxonica.com/html/documentation/extensibility/integratedfunctions/ 您可以在 Saxon 9(所有版本)中使用来调用 Java 代码。在 Saxon 9 PE 和 EE 中,您还可以使用自反扩展函数直接从 XSLT 代码调用 Java 代码。
再次感谢 Martin,你真的帮了我大忙!我使用 integrated extension functions 功能编写了自己的自定义 xslt 函数。该函数调用 java 方法,该方法测试文件是否存在于给定目录中并且 return 是真还是假。对于那些需要 "integrated extension functions" 功能的工作示例,或者甚至想测试 saxon-9-HE 是否存在文件的人,我将分享我的简单解决方案。
Java class 定义 xslt 函数名称、参数和 return 类型,并在调用 xslt 函数时包含要调用的 java 方法:
package de.mypackage.xsltfunctions;
import java.io.File;
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.BooleanValue;
import net.sf.saxon.value.SequenceType;
import net.sf.saxon.value.StringValue;
public class FileExists extends ExtensionFunctionDefinition {
@Override
public StructuredQName getFunctionQName() {
return new StructuredQName("file", "http://mydomain.de/xslt/filesystem", "file-exists");
}
@Override
public SequenceType[] getArgumentTypes() {
return new SequenceType[] { SequenceType.SINGLE_STRING, SequenceType.SINGLE_STRING };
}
@Override
public SequenceType getResultType(final SequenceType[] suppliedArgumentTypes) {
return SequenceType.SINGLE_BOOLEAN;
}
@Override
public ExtensionFunctionCall makeCallExpression() {
return new ExtensionFunctionCall() {
@Override
public Sequence call(final XPathContext context, final Sequence[] arguments)
throws XPathException {
String searchDir = ((StringValue) arguments[0]).getStringValue();
String fileName = ((StringValue) arguments[1]).getStringValue();
if (!new File(searchDir).isDirectory()) {
throw new XPathException(
"First argument \"" + searchDir + "\" is not a directory or cannot be found!");
}
return BooleanValue.get(new File(searchDir + fileName).exists());
}
};
}
}
为 saxon 处理器注册自定义 xslt-function 的代码片段:
import java.io.StringWriter;
import de.mypackage.xsltfunctions.FileExists;
import net.sf.saxon.TransformerFactoryImpl;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
StringWriter xmlResultResource = new StringWriter();
System.setProperty("javax.xml.transform.TransformerFactory","net.sf.saxon.TransformerFactoryImpl");
TransformerFactory factory = TransformerFactory.newInstance();
TransformerFactoryImpl tFactoryImpl = (TransformerFactoryImpl) factory;
net.sf.saxon.Configuration saxonConfig = tFactoryImpl.getConfiguration();
saxonConfig.registerExtensionFunction(new FileExists());
Transformer transformer = factory.newTransformer(new StreamSource(getXslFile()));
transformer.transform(new StreamSource(xmlFileInput), new StreamResult(xmlResultResource));
String result = xmlResultResource.getBuffer().toString();
当我 运行 我的 xsl 样式表时,我需要知道是否存在某些文件。因为 xslt 没有本地方法来测试文件是否存在 (ASFAIK),所以我想用 javascript 来做这个。通常我使用 saxon 9 HE,但一些同事告诉我 java脚本函数不受 HE 版本的支持。有没有办法用 saxon 9 HE 执行 java 脚本函数?
我试过这个例子:How to include javaScript file in xslt,但是氧气给了我这个错误:"Cannot find a matching 1-argument function named".
您可以使用 XPath 函数 doc-available
https://www.w3.org/TR/xpath-functions/#func-doc-available and unparsed-text-available
https://www.w3.org/TR/xpath-functions/#func-unparsed-text-available 检查是否存在 XML 文档或 non-XML 文本文档。
不支持在 Saxon 9 中使用 Javascript(并且简单的 ECMAScript/Javascript 引擎通常不包含任何文件 IO 功能)但是有一个称为集成扩展功能的功能 http://saxonica.com/html/documentation/extensibility/integratedfunctions/ 您可以在 Saxon 9(所有版本)中使用来调用 Java 代码。在 Saxon 9 PE 和 EE 中,您还可以使用自反扩展函数直接从 XSLT 代码调用 Java 代码。
再次感谢 Martin,你真的帮了我大忙!我使用 integrated extension functions 功能编写了自己的自定义 xslt 函数。该函数调用 java 方法,该方法测试文件是否存在于给定目录中并且 return 是真还是假。对于那些需要 "integrated extension functions" 功能的工作示例,或者甚至想测试 saxon-9-HE 是否存在文件的人,我将分享我的简单解决方案。
Java class 定义 xslt 函数名称、参数和 return 类型,并在调用 xslt 函数时包含要调用的 java 方法:
package de.mypackage.xsltfunctions;
import java.io.File;
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.BooleanValue;
import net.sf.saxon.value.SequenceType;
import net.sf.saxon.value.StringValue;
public class FileExists extends ExtensionFunctionDefinition {
@Override
public StructuredQName getFunctionQName() {
return new StructuredQName("file", "http://mydomain.de/xslt/filesystem", "file-exists");
}
@Override
public SequenceType[] getArgumentTypes() {
return new SequenceType[] { SequenceType.SINGLE_STRING, SequenceType.SINGLE_STRING };
}
@Override
public SequenceType getResultType(final SequenceType[] suppliedArgumentTypes) {
return SequenceType.SINGLE_BOOLEAN;
}
@Override
public ExtensionFunctionCall makeCallExpression() {
return new ExtensionFunctionCall() {
@Override
public Sequence call(final XPathContext context, final Sequence[] arguments)
throws XPathException {
String searchDir = ((StringValue) arguments[0]).getStringValue();
String fileName = ((StringValue) arguments[1]).getStringValue();
if (!new File(searchDir).isDirectory()) {
throw new XPathException(
"First argument \"" + searchDir + "\" is not a directory or cannot be found!");
}
return BooleanValue.get(new File(searchDir + fileName).exists());
}
};
}
}
为 saxon 处理器注册自定义 xslt-function 的代码片段:
import java.io.StringWriter;
import de.mypackage.xsltfunctions.FileExists;
import net.sf.saxon.TransformerFactoryImpl;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
StringWriter xmlResultResource = new StringWriter();
System.setProperty("javax.xml.transform.TransformerFactory","net.sf.saxon.TransformerFactoryImpl");
TransformerFactory factory = TransformerFactory.newInstance();
TransformerFactoryImpl tFactoryImpl = (TransformerFactoryImpl) factory;
net.sf.saxon.Configuration saxonConfig = tFactoryImpl.getConfiguration();
saxonConfig.registerExtensionFunction(new FileExists());
Transformer transformer = factory.newTransformer(new StreamSource(getXslFile()));
transformer.transform(new StreamSource(xmlFileInput), new StreamResult(xmlResultResource));
String result = xmlResultResource.getBuffer().toString();