当使用Saxon时,我试图从java代码中抛出异常,它将包含来自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行为?
发布于 2015-11-04 22:55:00
这是由于MessageEmitter正在向其发送消息的消息侦听器。在saxon 9.6中,默认的侦听器实现了UnfailingErrorListener,它不能抛出异常(就像9.6中的所有其他侦听器一样),但是在9.4中可以抛出来自侦听器的异常。
但是,您可以实现自己的消息发射器,它会在遇到xml:message时抛出异常,并将terminate设置为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时,将抛出异常
发布于 2015-10-31 13:50:38
不幸的是,新的Processing terminated...消息是用net.sf.saxon.expr.instruct.Message (9.6.0-7中的Message.java:253)硬编码的。以下是一个解决方法,它可能会满足您的需求:
public static void main(String[] args) throws TransformerException {
final StringWriter messageOut = new StringWriter();
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 MessageEmitter() {
@Override
public void open() throws XPathException {
setWriter(messageOut);
super.open();
}
});
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() + " <<<");
String message = messageOut.toString(); // this is the "exception message\n" that you want
// not sure why it has a \n on it
System.out.println("THIS IS THE MESSAGE WE WANT: " + message);
throw new TransformerException(message, e); // rethrow using the captured message, if you really want that "exception message" available to a caller in e.getMessage()
}
}https://stackoverflow.com/questions/33349610
复制相似问题