Dynamic XQuery using saxon:evaluate not working in Oxygen with an XPath 3.1 type expression?

57 Views Asked by At

I'm interested in using the saxon:evaluate in an XQuery (using the Oxygen XML Editor 24.0) and wanted to see it working in a very simple example using XPath 3.1 type expression so I can select a value from a parsed JSON object (using Saxon-EE XQuery 9.9). However in doing so I get an error returned reporting Static error in XPath expression supplied to saxon:evaluate: The XPath parser is not configured to allow use of XPath 3.1 syntax?

I tried the below:


let $rawJ :=
                    <jroot><![CDATA[
                                 {
                                    "siam_envelope": 
                                    {
                                        "protocol_version": "1"
                                    }
                                    }]]>
                    </jroot>
let $j := parse-json($rawJ)
let $expression := "$p1?siam_envelope?protocol_version"
let $result := saxon:evaluate($expression, $j)

return $result

I expected this to return the value "1" but instead it reported the "Static error in XPath expression supplied to saxon:evaluate: The XPath parser is not configured to allow use of XPath 3.1 syntax"

Presumably, this is because I'm using a map type XPath which is only supported in XPath 3.1. However, since the error reports "not configured" then I'm holding some hope that there's some configuration I can apply to get this working? If not, does anyone in this community know how to run a dynamic XPath 3.1 type expression in XQuery? Surely this must be possible?

Thanks in advance for any useful suggestions!

1

There are 1 best solutions below

1
On

Without using Saxon specific extensions, you can use fn:transform with xsl:evaluate:

declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";

declare option output:method 'adaptive';
declare option output:indent 'yes';

declare function local:eval($expression as xs:string, $context-item as item()?) as item()* {
  transform(
    map {
      'stylesheet-node' : <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" 
        xmlns:mf="http://example.com/mf"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="#all">
        <xsl:function name="mf:eval" as="item()*" visibility="public">
          <xsl:param name="expression" as="xs:string"/>
          <xsl:param name="context-item" as="item()?"/>
          <xsl:evaluate xpath="$expression" context-item="$context-item"/>
        </xsl:function>
      </xsl:stylesheet>,
      'initial-function' : QName('http://example.com/mf', 'eval'),
      'function-params': [$expression, $context-item],
      'delivery-format': 'raw'
    }
  )?output
};

let $rawJ :=
                    <jroot><![CDATA[
                                 {
                                    "siam_envelope": 
                                    {
                                        "protocol_version": "1"
                                    }
                                    }]]>
                    </jroot>
let $j := parse-json($rawJ)
let $expression := "?siam_envelope?protocol_version"
let $result := local:eval($expression, $j)
 
return $result

That should work with any XQuery 3.1 implementation supporting fn:transform and xsl:evaluate, so in the case of Saxon for HE that means 10 or later or for PE or EE I think 9.8 or later.