使用 XPath 从参数映射构建 URL 查询字符串

Mar*_*ius 3 xpath xpath-3.0 xslt-3.0

从 XSLT/XPath 3.0 中的映射构建 URL 查询字符串的最易读的方法是什么{ 'param': 'value' }

ree*_*ece 5

以下功能将起作用:

declare function local:build-uri($base-uri as xs:string, $params as map(xs:string, xs:string)) as xs:string {
  if (map:size($params) ne 0) then
    let $param-string := string-join(
        map:keys($params)[. ne ""] ! (encode-for-uri(.) || "=" || encode-for-uri($params?(.))),
        "&"
      )
    return $base-uri || "?" || $param-string
  else
    $base-uri
};
Run Code Online (Sandbox Code Playgroud)

例如:

declare namespace map = "http://www.w3.org/2005/xpath-functions/map";
declare variable $params := map {
  "one": "1",
  "two": "2",
  "three": "3",
  "four": "4"
};

local:build-uri("http://www.example.com", map{}),
local:build-uri("http://www.example.com", $params),
local:build-uri("", $params),
()
Run Code Online (Sandbox Code Playgroud)

返回:

http://www.example.com
http://www.example.com?four=4&one=1&two=2&three=3
?four=4&one=1&two=2&three=3
Run Code Online (Sandbox Code Playgroud)

编辑:为了支持多值参数(同时保持函数体与 XPath 兼容),类似这样的东西应该可以工作:

declare function local:build-uri(
  $base-uri as xs:string,
  $params as map(xs:string, xs:string*),
  $use-array-for-multivalue-params as xs:boolean (: param[]=value for PHP, etc. :)
) as xs:string {
  if (map:size($params) ne 0) then
    let $param-strings :=
      for $param in map:keys($params)[. ne '']
      return $params?($param) ! string-join((
        encode-for-uri($param),
        if ($use-array-for-multivalue-params and count($params?($param)) gt 1) then "[]" else "",
        "=",
        encode-for-uri(.)
      ), "")
    return $base-uri || "?" || string-join($param-strings, "&")
  else
    $base-uri
};
Run Code Online (Sandbox Code Playgroud)