2015-10-26 3 views
5

Saxonを使用しているときにxsl:messageタグからのメッセージを含むjavaコードから例外をスローしようとしています。次のコードxslt:Saxon 9.4のメッセージSaxon 9.6のメッセージ

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

とサクソン9.4で、次の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> 

を使用して

それは私が期待してい行動である、THIS IS EXCEPTION: exception message <<<を与えます。なぜならAPIの少し調整コード付き

しかし、サクソン9.6には

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を与える:メッセージはどこかに失われます。

「9.6」で「9.4」の動作を達成するにはどうすればよいですか?

答えて

1

残念ながら、新しい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() 
    } 
} 
3

これはMessageEmitterがメッセージを送信しているメッセージリスナーによるものです。 saxon 9.6では、デフォルトのリスナーは例外をスローできないUnfailingErrorListenerを実装しています(9.6の他のすべてのリスナーと同じですが)。9.4ではリスナーから例外をスローすることができました。

ただし、XMLに遭遇したときに例外をスローすることを、独自のメッセージエミッタを実装できます。

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

し、その後、このようにそれを登録します:

このようにyesに設定TERMINATEのメッセージを、
transformer.getUnderlyingController().setMessageEmitter(new ExceptionThrowingMessageEmitter()); 

この方法では、例外は、XMLが終了したときに、スローされます:メッセージ

+0

XSLを取得するためにどのような方法がある場合は、あなたが知っていますか:メッセージ行/列数はエミッタを使用していますか? –

関連する問題