tom*_*mgi 6 java xml xslt saxon
我正在尝试从使用Saxon时包含来自xsl:message标签的消息的java代码中抛出异常.
使用以下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>
Run Code Online (Sandbox Code Playgroud)
在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;
}
}
Run Code Online (Sandbox Code Playgroud)
它给出了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;
}
}
Run Code Online (Sandbox Code Playgroud)
它给出THIS IS EXCEPTION: Processing terminated by xsl:message at line 4 in throw.xslt <<<
了xsl:消息丢失的地方.
如何在"9.6"上实现"9.4"行为?
小智 5
这是由于MessageEmitter向其发送消息的消息侦听器。在saxon 9.6中,默认侦听器实现了UnfailingErrorListener,它不能引发异常(与9.6中的所有其他侦听器一样),但是在9.4中,可以从侦听器引发异常。
但是,您可以实现自己的消息发射器,遇到终止设置为yes的xml:message时会抛出异常,如下所示:
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
}
}
Run Code Online (Sandbox Code Playgroud)
然后,像这样注册它:
transformer.getUnderlyingController().setMessageEmitter(new ExceptionThrowingMessageEmitter());
Run Code Online (Sandbox Code Playgroud)
这样,当终止xml:message时,将引发异常
不幸的是,新消息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()
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
628 次 |
最近记录: |