Menu

extension function returning a tree?

Help
2012-04-23
2012-10-08
  • Dieter Stüken

    Dieter Stüken - 2012-04-23

    I have written a java function dumping a database table to XML using SAX.

    Is it possible to turn it into an integrated extension function to call it
    from within saxon?
    The given example only return some atomic value like an number or string.

    Is it possible to get a ContentHandler or even a s9api.Destination to send my
    content to?
    I don't like to build an intermediate DOM tree myself
    (even if Saxon will do, as i currently use Saxon-HE which does not support
    streaming).

    The Saxon SQL extension seems to do to a very similar job, but I currently
    have to use HE :-(

    Dieter.

     
  • Michael Kay

    Michael Kay - 2012-04-23

    The Saxon SQL extension is open source, so you can study the source code.
    However, it uses extension instructions which are a rather different
    interface.

    If you're starting with lexical XML then wrap a StreamSource around it, and
    from the context object do context.getConfiguration().buildDocument(source).
    The result is a NodeInfo object, which you can turn into a SequenceIterator by
    wrapping it in a SingletonIterator. So it's something like:

    return new SingletonIterator(context.getConfiguration().buildDocument(new
    StreamSource(new StringReader(xml))))

     
  • Barry Demchak

    Barry Demchak - 2012-05-03

    Very helpful reply ... thanks, Mike! ... I need this, too.

    For the other half of the picture, I also need to pass a node into an
    ExtensionFunctionCall as a parameter.

    Certainly, I can get the parameter value with something like arguments.next(),
    but I'm not sure (exactly) what I'm getting.

    It looks like maybe it's a NodeInfo. (True??) If so, how do I convert it to
    XML?

    I have tried getStringValue, but I get text containing only data values
    concatenated, not the XML document. How would I get the XML document, too??

    Thanks!

     
  • Michael Kay

    Michael Kay - 2012-05-03

    NodeInfo is Saxon's representation of a node in an XML tree. If you've got a
    NodeInfo and you want to serialize it to lexical XML (ie. angle-brackets), the
    simplest way is the static method
    net.sf.saxon.query.QueryResult.serialize(NodeInfo node). There are other ways
    that give you more control over exactly how the node is serialized (e.g
    indentation, XML declaration, etc).

     
  • Barry Demchak

    Barry Demchak - 2012-05-04

    Thanks, Mike!

    That did the trick. The alternative I found was http://markmail.org/message/6
    okk3ig4n3b5ehun
    ... a not-so-
    pretty way of doing the same thing. I did find the QueryResult class, and had
    hoped it worked as advertised (which, I'm guessing is a pretty packaging of
    the not-so-pretty way). Between the documentation, my trying it, and your
    response, I'll happily and gratefully move on.

    The next step is to convert the XML to a Java object (using XStream). If there
    is a quicker round trip between NodeInfo and Java Object, would you let me
    know??

    (The Java Object will be passed on an Enterprise Service Bus to services that
    expect Java Objects.)

    Thanks!

     
  • Michael Kay

    Michael Kay - 2012-05-04

    If there is a quicker round trip between NodeInfo and Java Object

    I don't know anything about XStream, but many XML tools will accept input in
    the form of a stream of SAX events. If XStream supplies a SAX ContentHandler
    for supplying its input, then you can pump data into it from Saxon easily
    enough:

    ContentHander ch = XStream.giveMeAContentHandler();
    net.sf.saxon.event.ContentHandlerProxy proxy = new
    net.sf.saxon.event.ContentHandlerProxy();
    proxy.setUnderlyingContentHandler(ch);
    proxy.setPipelineConfiguration(node.getConfiguration().makePipelineConfigurati
    on());
    node.copy(proxy, 0, 0);