Menu

Returning result of Saxon Xpath as a string

Help
Anonymous
2011-04-25
2012-10-08
  • Anonymous

    Anonymous - 2011-04-25

    Hi!
    I'm currently converting some xml manipulation code to use Saxon and got a
    problem in returning the result of Saxon9 Xpath in a form of a string.

    Example XML input

    <Foo>
                  <Bar>
                         <Baz>1</Baz>
                         <Baz>2</Baz>
                  </Bar>
                  <Bar>
                        <Baz>3</Baz>
                        <Baz>4</Baz>
                        <Baz>5</Baz>
                        <Baz>6</Baz>
                  </Bar>
         </Foo>
    

    Xpath used: /Foo/Bar

    Below code:

        Configuration config = new Configuration();
            config.setLineNumbering(true);
            XPathEvaluator xpath = new XPathEvaluator();
            try {
                StringReader strRead = new StringReader("<Foo><Bar><Baz>1</Baz><Baz>2</Baz></Bar><Bar><Baz>3</Baz><Baz>4</Baz><Baz>5</Baz><Baz>6</Baz></Bar></Foo>");
                List results = (List) xpath.evaluate("/Foo/Bar", new StreamSource(strRead), XPathConstants.NODESET);
                for (int i=0; i<results.size(); i++) {
                    net.sf.saxon.tinytree.TinyNodeImpl  object = (net.sf.saxon.tinytree.TinyNodeImpl) results.get(i);
                    System.out.println(object.getNodeKind() + " " +  object.getDisplayName());
                    // Some code go here
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
            }
    

    We need to get the output as a string.
    <Bar>
    <Baz>1</Baz>
    <Baz>2</Baz>
    </Bar>

    <Bar>
    <Baz>3</Baz>
    <Baz>4</Baz>
    <Baz>5</Baz>
    <Baz>6</Baz>
    </Bar>

    Thank you very much for the help.

    Sincerely,
    Gerald.

     
  • Michael Kay

    Michael Kay - 2011-04-25

    First, I would suggest you cast to net.sf.saxon.om.NodeInfo rather than to
    net.sf.saxon.tinytree.TinyNodeImpl - NodeInfo is a much more stable and public
    interface.

    The simplest interface to serialize a NodeInfo object as XML is the static
    method net.sf.saxon.query.QueryResult.serialize(NodeInfo node). This sets the
    serialization options to indent=yes, omit-xml-declaration=yes, which appears
    to be what you are looking for. If you want more control, there is also a
    four-argument serialize() method in the same class.

     
  • Anonymous

    Anonymous - 2011-04-26

    Michael
    Thank you very much for the help it solve my problem.

    Sincerely,
    Gerald

     
  • Anonymous

    Anonymous - 2011-04-26

    Hi Michael,
    Got another question in returning the values of an attribute, is there a way
    for Saxon to return the values of an attribute in an XPath?

    XML Input

       <Foo>
                  <Bar sample="id1">
                         <Baz>1</Baz>
                         <Baz>2</Baz>
                  </Bar>
                  <Bar>
                        <Baz>3</Baz>
                        <Baz>4</Baz>
                        <Baz>5</Baz>
                        <Baz>6</Baz>
                  </Bar>
         </Foo>
    

    Xpath: /Foo/Bar/Baz/@sample

    Below Code:

    Configuration config = new Configuration();
            config.setLineNumbering(true);
            config.setAllNodesUntyped(true);
            XPathEvaluator xpath = new XPathEvaluator();
            try {
                StringReader strRead = new StringReader("<Foo><Bar><Baz sample=\"id1\">1</Baz><Baz>2</Baz></Bar><Bar><Baz>3</Baz><Baz>4</Baz><Baz>5</Baz><Baz>6</Baz></Bar></Foo>");
                List results = (List) xpath.evaluate("/Foo/Bar/Baz/@sample", new StreamSource(strRead), XPathConstants.NODESET);
                for (int i=0; i<results.size(); i++) {
                    NodeInfo  object = (NodeInfo) results.get(i);
                    Properties props = new Properties();
                    props.setProperty(OutputKeys.METHOD, "text");
                    props.setProperty(OutputKeys.ENCODING, "UTF-8");
                    props.setProperty("method", "xml");
                    props.setProperty(OutputKeys.INDENT, "yes");
                    props.setProperty(OutputKeys.STANDALONE, "true");
                    props.setProperty(OutputKeys.MEDIA_TYPE, "text");
                    props.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
                    props.setProperty(SaxonOutputKeys.WRAP, "yes");
                    StringWriter sw = new StringWriter();
                    QueryResult.serialize(object, new StreamResult(sw), props);
                    System.out.println(sw.toString());
                    System.out.println("");
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
            }
    

    Exception

    net.sf.saxon.event.NoOpenStartTagException: Cannot create an attribute node (sample) whose parent is a document node
        at net.sf.saxon.event.NoOpenStartTagException.makeNoOpenStartTagException(NoOpenStartTagException.java:49)
        at net.sf.saxon.event.TreeReceiver.attribute(TreeReceiver.java:189)
        at net.sf.saxon.tinytree.TinyAttributeImpl.copy(TinyAttributeImpl.java:185)
        at net.sf.saxon.event.TreeReceiver.append(TreeReceiver.java:295)
        at net.sf.saxon.query.QueryResult.serializeSequence(QueryResult.java:187)
        at net.sf.saxon.query.QueryResult.serialize(QueryResult.java:116)
        at com.ti.itg.peit.core.xml.util.XMLUtil.main(XMLUtil.java:110)
    

    Thank you very much.

    Sincerely,
    Gerald