我正在尝试从 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/