jx函数在xslt中使用saxon 9 HE

时间:2018-04-03 15:04:51

标签: xml xslt saxon oxygenxml

当我运行我的xsl样式表时,我需要知道是否存在某些文件。因为xslt没有本机方式来测试文件是否存在(ASFAIK),所以我想用javascript来做这件事。通常我会使用saxon 9 HE,但有些同事告诉我,HE版本不支持javascript功能。有没有办法用saxon 9 HE执行java脚本函数?

我试过这个例子:How to include javaScript file in xslt,但氧气给了我这个错误:"找不到一个名为&#34的匹配的1参数函数。

2 个答案:

答案 0 :(得分:3)

您可以使用XPath函数doc-available https://www.w3.org/TR/xpath-functions/#func-doc-availableunparsed-text-available https://www.w3.org/TR/xpath-functions/#func-unparsed-text-available来检查XML文档或非XML文本文档是否存在。

不支持在Saxon 9中使用Javascript(并且简单的ECMAScript / Javascript引擎通常不包含任何文件IO功能)但是有一个功能称为集成扩展函数http://saxonica.com/html/documentation/extensibility/integratedfunctions/,您可以在Saxon中使用9(所有版本)调用Java代码。在Saxon 9 PE和EE中,您还可以使用自反扩展函数直接从XSLT代码调用Java代码。

答案 1 :(得分:2)

再次感谢马丁,你真的帮帮我了!我使用integrated extension functions功能编写了自己的自定义xslt函数。该函数调用java方法,该方法测试文件是否存在于给定目录中并返回true或false。对于那些需要"集成扩展功能的工作示例的人来说#34;功能,甚至想测试saxon-9-HE中是否存在文件,我将分享我的简单解决方案。

Java类,它定义xslt函数名,参数和返回类型,并在调用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());
      }
    };
  }

}

代码剪切,为撒克逊处理器注册自定义xslt函数:

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();