2015-10-26 16 views
5

Tôi đang cố gắng ném ngoại lệ từ mã java sẽ bao gồm thông báo từ thẻ xsl: message khi sử dụng Saxon.xslt: tin nhắn trong Saxon 9.4 vs Saxon 9.6

Sử dụng tập tin XSLT sau

<?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> 

On Saxon 9.4 với đoạn mã sau

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; 
    } 
} 

nó mang lại cho THIS IS EXCEPTION: exception message <<<, đó là hành vi của tôi đang mong đợi.

Nhưng trên Saxon 9.6 với một ít mã đã điều chỉnh do thay đổi 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; 
    } 
} 

nó mang lại cho THIS IS EXCEPTION: Processing terminated by xsl:message at line 4 in throw.xslt <<< và xsl: thông điệp được ở đâu đó mất.

Làm cách nào để đạt được hành vi "9.4" trên "9.6"?

Trả lời

1

Thật không may, thông báo Processing terminated... mới được mã hóa cứng trong net.sf.saxon.expr.instruct.Message (Message.java:253 trong 9.6.0-7). Đây là giải pháp có thể cung cấp cho bạn những gì bạn cần:

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() 
    } 
} 
3

Điều này là do người nghe tin nhắn, mà MessageEmitter đang gửi tin nhắn. Trong saxon 9.6, người nghe mặc định đang triển khai UnfailingErrorListener mà không thể ném ngoại lệ (như tất cả các trình nghe khác trong 9.6), nhưng trong 9.4 nó có thể ném ngoại lệ từ người nghe.

Tuy nhiên, bạn có thể thực hiện phát thông điệp của riêng bạn, điều đó sẽ ném một ngoại lệ khi gặp phải xml: nhắn với chấm dứt thiết lập để có, như thế này:

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 
    } 
} 

và sau đó, đăng ký nó như thế này:

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

bằng cách này, ngoại lệ sẽ được ném ra, khi có sự chấm dứt xml: thông điệp

+0

bạn có biết nếu có cách nào để có được xsl: thông báo số dòng/cột bằng Emitter? –

Các vấn đề liên quan