tags:

views:

280

answers:

1

Hi all,

I what to use XQuery to convert string like "aaa=1&bbb=2" into xml

<request>
  <aaa>1</aaa>
  <bbb>2</bbb>
</request>

I have tried the following code, but failed!

xquery version "1.0" encoding "GBK";
(:: pragma  type="xs:anyType" ::)

declare namespace xf = "http://tempuri.org/BNetAP/Xquery/query2xml/";

declare function xf:query2xml($queryStr as xs:string)
    as element(*) {
    <query-params>
    {
     for $c in
      fn:tokenize($queryStr, "&amp;")
     let $myname as xs:string := "{fn:substring-before($c,"=")}"
     return 
      element
       {fn:QName("", $myname)}
       {"{fn:substring-after($c,"=")}"}
    }
    </query-params>
};

The error message is:

line 15, column 6:  "{http://www.w3.org/2004/07/xpath-functions}QName": unknown function (or number of arguments (2) is wrong)  BNetAP/Xquery query2xml.xq line 15 1241431186406 397

I have no idea why "QName" is a "unknow function"?!

A: 

You should be using the constructor xs:QName, not fn:QName.

The body of your constructed element also looks a bit suspicious:

"{fn:substring-after($c,"=")}"

is in fact a comparison between the string "{fn:substring-after($c," and the string ")}" so the content of the element would just be the text "false".

Similarly you $myname variable is actually being set to false and so will raise a type check error at run time.

Your function should probably be as follows:

declare function xf:query2xml($queryStr as xs:string)
    as element(*) {
  <query-params>
  {
    for $c in fn:tokenize($queryStr, "&amp;")
    let $myname := fn:substring-before($c,"=")
    return 
      element
        {xs:QName("", $myname)}
        {fn:substring-after($c,"=")}
  }
  </query-params>
};

A computed element constructor can also accept just a string for its name, so your return expression could be simplified to just

return element {$myname} {fn:substring-after($c,"=")}
Oliver Hallam