Re: "Faking" a message for a MessageListener

Michael Kay <mike-JkSD5nQpfvpWk0Htik3J/[email protected]> Tue, 27 Apr 2021 08:53:09 +0100
Newsgroups gmane.text.xml.saxon.help
Message-ID <[email protected]>
It's taken quite a few iterations to come up with the right API for xsl:message handling, and in fact we're changing it again in Saxon 11: the new interface will be 

setMessageHandler(Consumer<Message> handler)

where Message is an object that encapsulates the message content (an XML document), the error code, the location of the originating instruction, etc. Hopefully this is simple enough and abstract enough that it will prove a long term solution. This is a functional interface so you can write it as a lambda expression:

setMessageHandler(msg -> myLogger.log(msg.content));

The mistakes we've made along the way have included:

(a) Thread safety (don't even think about the case where the xsl:message instruction contains a multi-threaded xsl:for-each...)

(b) Avoiding interfaces like ErrorListener that require you to construct a Java Exception, which is notoriously expensive and a totally unnecessary overhead

(c) Making it easy to handle the common case of simple text messages while also handling the general case where a message is an XML document.

Regarding your specific question, How to create an XdmNode representing an XML Document node containing a single text node child? I think the simplest answer in Saxon 10 is the new sapling interface:

new SaplingDocument().withChild(new SaplingText(messageContent)).toXdmNode();

Michael Kay
Saxonica

> On 26 Apr 2021, at 17:53, Jeremy Cronk <[email protected]> wrote:
> 
> I’ve been trying to create a facade for Saxon and Xalan, and while I’ve gotten everything else the way I need it, I’m running into a problem with handling xsl:message instructions.  Xalan uses an ErrorListener to pass any messages, and I’ve figured out that I can tell the difference between a Xalan message and a warning by inspecting the call stack.  The next thing I want to do is take the message and SourceLocator from the TransformerException passed into the warning method and send that to a MessageListener or MessageListener2.  That way I’m preserving a clear distinction between messages and errors/warnings, and it seems like a waste not to make use of the MessageListener interface since it’s available. 
>  
> Basically what I have in mind is that I’ll accept an ErrorListener and a MessageListener, set them normally for Saxon transformations, and for Xalan transformations, set an ErrorListener that either delegates to the provided one or, in the case of xsl:messages, calls the message method of the MessageListener.  In principle this could all work, were it not for the fact that I can’t figure out how to create an XdmNode to pass to the message method. 
>  
> If I check out what Saxon passes to a MessageListener, it looks like an XdmNode that contains text, but somehow the underlying NodeInfo is a document node from  net.sf.saxon.tree.linked.DocumentImpl.  If I use a DocumentBuilder, first, I have to take the string message and wrap it in a tag (or else I get a parse error), and then what I get back is a net.sf.saxon.tree.tiny.TinyDocumentImpl.  I was hoping I could manage a way of getting the text node back as an XdmNode but nothing I’ve tried has worked.  
>  
> The problem all this is intended to solve is basically reporting - we need a way using both XSLT 1.0 with Xalan (this is legacy code that makes heavy use of EXSLT fn:functions) and XSLT 3.0 code with Saxon to report business-related issues with input data that would be difficult or impossible to handle using schema validation.  So if I’m clearly headed down the wrong path, I’m open to other suggestions.  Otherwise, is there a way to slip plain, non-tagged text into an XdmNode that won’t cause a bunch of problems?  Even if it’s a hacky way that won’t necessarily be stable across multiple versions of Saxon, pretty much anything would be useful at this point.
>  
> I hope all of this makes at least some kind of sense. 
>  
> Thanks!
>  
> Jeremy 
>  
>  
> _______________________________________________
> saxon-help mailing list archived at http://saxon.markmail.org/ <http://saxon.markmail.org/>
> [email protected] <mailto:[email protected]>
> https://lists.sourceforge.net/lists/listinfo/saxon-help <https://lists.sourceforge.net/lists/listinfo/saxon-help>

_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[email protected]
https://lists.sourceforge.net/lists/listinfo/saxon-help