user29408236
user29408236

Reputation: 1

Not able to set output:method "text" in Xquery

declare namespace xf = "http://tempuri.org//test"  
declare namespace output ="http://​www.​w3.​org/​2010/​xslt-​xquery-​ser​iali​zati​on";  
declare option output: method "text";

declare function xf:test($test as element(*)) as item () * {

for $row in $test/*:row  
return ('"<row", "',data($row), '"')

};

declare variable $test as element(*) external;  
xf:test($test)

Even after adding declare option output: method "test"; the output is not in text format . I can set output method "text" using Saxon API, but its not working directly in xquery.

Input xml

<all>
 <row>one</row>
 <row>two</row>
 <row>three</row>
<all>

Actual Output

"&lt;row&gt;", "one"
"&lt;row&gt;", "two"
"&lt;row&gt;", "three"

Expected Output

"<row>","one"
"<row>","two"
"<row>","three"

Here is the sample code . When i use getSerializationParameters and set property , it works in the API.

import com.saxonica.xqj.SaxonXQDataSource;

public static void main(String[] args) throws Exception {

        InputStream inputStream = new FileInputStream(
                new File("resources/META-INF/xquery//test.xq"));
        SaxonXQDataSource ds = new SaxonXQDataSource();
        Configuration a = ds.getConfiguration();
        ((SaxonXQDataSource) ds).getConfiguration().getDefaultStaticQueryContext()
                .setLanguageVersion(30);
        a.getDefaultStaticQueryContext().setLanguageVersion(31);
        XQConnection conn = ds.getConnection();
        XQPreparedExpression exp = conn.prepareExpression(inputStream);

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        InputStream payloadInputStream = new FileInputStream(
                new File("resources/META-INF/msgs/MsgReq6.xml"));
        String payloadMsg = null;
        try (Scanner scanner = new Scanner(payloadInputStream, StandardCharsets.UTF_8.name())) {
            payloadMsg = scanner.useDelimiter("\\A").next();
        }
        exp.bindNode(new QName("test"), convertStringToDocument(payloadMsg).getDocumentElement(),
                null);
        XQResultSequence result = exp.executeQuery();
        while (result.next()) {
            System.out.println(result.getItemAsString(getSerializationParameters()));
        }

    }

public static Properties getSerializationParameters() {
        Properties properties = new Properties();
        properties.setProperty("method", "text");
        return properties;
    }

    public static Document convertStringToDocument(String xmlStr) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder;
        try {
            builder = factory.newDocumentBuilder();
            Document doc = builder.parse(new InputSource(new StringReader(xmlStr)));
            return doc;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

Upvotes: 0

Views: 80

Answers (1)

Michael Kay
Michael Kay

Reputation: 163587

I believe that the XQJ API does not support serialization using parameters defined within the query.

Unfortunately one of the rules of the XQJ license conditions is that if you implement the API, you aren't allowed to extend it, so Saxon does what the XQJ spec says and nothing more. (On one interpretation Saxon is even in breach of those license conditions simply by allowing XQuery 3.1 to be used via this API).

I think XQJ is a dead end and would encourage you to use Saxon's s9api interface instead.

You might be able to escape from the XQJ view of the world into the underlying Saxon classes: cast the XQExecutable to a SaxonXQExecutable, from that get the Saxon XQueryExpression, then the (Saxon) Executable, from that getPrimarySerializationProperties().getProperties() and then you can feed these properties back into XQJ. But that's so tortuous that by the time you've done this, you've lost any benefits you might have gained by using a "standard" API rather than Saxon's native API.

Upvotes: 0

Related Questions