Saxon 9 HE, Java - Stati c ошибки, XTSE0210, XTSE0165, XPST0017 - PullRequest
0 голосов
/ 13 марта 2020

При вызове XSL-преобразования с использованием Saxon из моего приложения я получаю следующую ошибку

Static error at xsl:import on line 34 column 45 
  XTSE0210: A stylesheet cannot import itself
Static error at xsl:import on line 42 column 39 
  XTSE0165: Reported 1 error in imported stylesheet module
Static error in {leg:IsCurrentWelsh(/)} in expression in xsl:when/@test on line 101 column 43 
  XPST0017: Cannot find a 1-argument function named

.
.
.
net.sf.saxon.trans.XPathException: Errors were reported during stylesheet compilation
    at net.sf.saxon.style.StylesheetModule.loadStylesheet(StylesheetModule.java:260) ~[Saxon-HE-9.8.0-15.jar:na]
    at net.sf.saxon.style.Compilation.compileSingletonPackage(Compilation.java:106) ~[Saxon-HE-9.8.0-15.jar:na]
    at net.sf.saxon.s9api.XsltCompiler.compile(XsltCompiler.java:739) ~[Saxon-HE-9.8.0-15.jar:na]
    at net.sf.saxon.jaxp.SaxonTransformerFactory.newTemplates(SaxonTransformerFactory.java:155) ~[Saxon

Однако при вызове Saxon из командной строки он работает успешно.

java -jar saxon9he.jar xml.xml {path-to-my-xslt}

Код, вызывающий XSLT в моем приложении Java, выглядит следующим образом ...

  public static String transform(Document inputDoc, String xslDoc, Map<String, Object> params, String xslContextPath) throws XmlException {

    try {
      System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
      TransformerFactory factory = TransformerFactory.newInstance();
      factory.setURIResolver(new ClasspathResourceURIResolver(xslContextPath));
      factory.setAttribute(FeatureKeys.GENERATE_BYTE_CODE, false);

      Templates template = factory.newTemplates(new StreamSource(new StringReader(xslDoc)));

      Transformer xformer = template.newTransformer();

      if (params != null) {
        for (Map.Entry<String, Object> entry : params.entrySet()) {
          xformer.setParameter(entry.getKey(), entry.getValue());
        }
      }

      ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
      DOMSource domSource = new DOMSource(inputDoc);


      xformer.transform(domSource, new StreamResult(outputStream));

      return outputStream.toString("UTF-8");

    } catch (TransformerConfigurationException e) {
      throw new XmlException(e);

    } catch (TransformerException e) {
      SourceLocator locator = e.getLocator();
      if (locator != null) {
        Map<String, Object> message = new HashMap<String, Object>();
        message.put("col", locator.getColumnNumber());
        message.put("line", locator.getLineNumber());
        message.put("publicId", locator.getPublicId());
        message.put("systemId", locator.getSystemId());
        throw new XmlException(message.toString(), e);
      }
      throw new XmlException(e);

    } catch (Exception e) {
      throw new XmlException(e);
    }
  }

другие параметры не передаются ни для одного из случаев.

Это используется Саксонский 9.8.0-15he. В большинстве случаев приведенный выше код работает нормально, и мы долгое время использовали его без проблем, это когда я вызываю конкретный XSLT, который имеет серию импортов, слишком большой для воспроизведения здесь.

Есть идеи, что может потребоваться изменить код, чтобы он работал?

Странно запускать тот же код через Saxon 9.4he, работает.

1 Ответ

0 голосов
/ 13 марта 2020

Когда вы делаете

Templates template = factory.newTemplates(new StreamSource(new StringReader(xslDoc)));

, вы не предоставляете системный идентификатор (базовый URI) для таблицы стилей. Напротив, когда вы запускаете из командной строки, Saxon может определить базовый URI из предоставленного имени файла. Я не знаю точно, почему это не удается, потому что вы не предоставили достаточно информации, но я подозреваю, что это основная причина разницы. Поскольку Saxon имеет неполную информацию о базовых URI модулей стилей, он, вероятно, думает, что два модуля одинаковы, когда они не являются.

Вы можете указать идентификатор системы в качестве второго аргумента new StreamSource().

...