java - xslt:Saxon 9.4 与 Saxon 9.6 中的消息

标签 java xml xslt saxon

我正在尝试从 java 代码中抛出异常,该异常将在使用 Saxon 时包含来自 xsl:message 标记的消息。

使用下面的 xslt 文件

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <xsl:message terminate="yes">exception message</xsl:message>
    </xsl:template>
</xsl:stylesheet>

在 Saxon 9.4 上使用以下代码

public static void main(String[] args) throws TransformerException {
    try {
        TransformerFactory fact = new net.sf.saxon.TransformerFactoryImpl();
        Transformer newTransformer = fact.newTransformer(new StreamSource(new File("throw.xslt")));
        ((net.sf.saxon.Controller)newTransformer).setRecoveryPolicy(Configuration.DO_NOT_RECOVER);
        ((net.sf.saxon.Controller)newTransformer).setMessageEmitter(new MessageWarner());
        newTransformer.transform(new StreamSource(new File("input.xml")), new StreamResult(new File("output.xml")));
    } catch (TransformerException e) {
        System.out.println("THIS IS EXCEPTION: " + e.getMessage() + " <<<");
        throw e;
    }
}   

它给出 THIS IS EXCEPTION: exception message <<< ,这是我期望的行为。

但在 Saxon 9.6 上,由于 API 更改,代码略有调整

public static void main(String[] args) throws TransformerException {
    try {
        TransformerFactory fact = new net.sf.saxon.TransformerFactoryImpl();
        Transformer newTransformer = fact.newTransformer(new StreamSource(new File("throw.xslt")));
        ((net.sf.saxon.jaxp.TransformerImpl)newTransformer).getUnderlyingController().setRecoveryPolicy(Configuration.DO_NOT_RECOVER);
        ((net.sf.saxon.jaxp.TransformerImpl)newTransformer).getUnderlyingController().setMessageEmitter(new MessageWarner());
        newTransformer.transform(new StreamSource(new File("input.xml")), new StreamResult(new File("output.xml")));
    } catch (TransformerException e) {
        System.out.println("THIS IS EXCEPTION: " + e.getMessage() + " <<<");
        throw e;
    }
}

它给出 THIS IS EXCEPTION: Processing terminated by xsl:message at line 4 in throw.xslt <<<并且 xsl:message 丢失了。

如何在“9.6”上实现“9.4”的行为?

最佳答案

这是由于 MessageEmitter 正在向其发送消息的消息监听器。在 saxon 9.6 中,默认监听器正在实现 UnfailingErrorListener,它不能抛出异常(与 9.6 中的所有其他监听器一样),但在 9.4 中,可以从监听器中抛出异常。

但是,您可以实现自己的消息发射器,这会在遇到 xml:message 且终止设置为 yes 时抛出异常,如下所示:

final class ExceptionThrowingMessageEmitter extends XMLEmitter {
  boolean abort = false;

  public void startDocument(int properties) throws XPathException {
    setWriter(new StringWriter());
    abort = (properties & ReceiverOptions.TERMINATE) != 0;
    super.startDocument(properties);
  }

  public void endDocument() throws XPathException {
    XPathException de = new XPathException(getWriter().toString());
    de.setErrorCode("XTMM9000");
    if (abort) {
      throw de;
    } else {
      //terminate set to no, do something like writing to the log file
    }
  }

  public void close() {
    // do nothing
  }
}

然后,像这样注册它:

transformer.getUnderlyingController().setMessageEmitter(new ExceptionThrowingMessageEmitter());  

这样,当有终止 xml:message 时,将抛出异常

关于java - xslt:Saxon 9.4 与 Saxon 9.6 中的消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33349610/

相关文章:

java - 使用LocalDateTIme和ZonedDateTime从日期中减去一天后得到错误的结果

xml - XML 文档中双花括号内的语句?

java - 使用 proguard 混淆 JavaFX 应用程序时出错

java - 将 Python JSON API 移植到 Java (GWT)

java - 为什么 Spring 的 @Transactional 不适用于 protected 方法?

xml - 使用环境变量的 Maven 本地存储库

java - 如何在 Hadoop Mapper 中处理 XML 文件

从 UTF-8 到 ISO-8859-1 的 Java 编码为 XML 文件

xml - 更改上下文节点的 XSLT 指令/函数列表?

xml - 使用 XQUERY 从 XML 中消除单个元素类型