4

XQuery 中是否有对数组的内置支持?例如,如果我们想在 xquery 中实现简单的 java 程序,我们会怎么做:

(我不是要求将整个程序翻译成 xquery,而只是询问如何将下面代码的第 2 行中的数组实现为 xquery?我也在使用 marklogic / xdmp 函数)。

java.lang.String test = new String("Hello XQuery");
char[] characters = test.toCharArray();

for(int i = 0; i<characters.length; i++) {
    if(character[i] == (char)13) { 
        character[i] = (char) 0x00;
    }
}

Legend:

hex 0x00 dec 0 : null
hex 0x0d dec 13: carriage return
hex 0x0a dec 10: line feed
hex 0x20 dec 22: dquote
4

7 回答 7

6

将示例代码转换XQuery为的问题不是不支持数组,而是x00不是XML. 如果不是这个问题,您可以使用简单的函数调用来表达您的查询:

translate($input, '&#x13;', '&#x00;')

现在,您可以争辩说这是作弊,它只是发生了,因此有一个功能可以完全按照您的手动操作来完成。但是如果这个函数不存在,你可以将它编程为XQuery:有足够的原语可用于字符串,允许你以任何你想要的方式操作它们。如果您需要(并且很少需要),您可以使用函数将字符串转换为整数序列string-to-codepoints(),然后利用所有XQuery工具来操作序列。

教训是,当您使用XQueryor之类的声明性语言时XSLT,不要尝试使用在更原始语言中被迫使用的相同低级编程技术。通常有一种更直接的方式来表达问题。

于 2012-12-20T08:44:48.533 回答
3

XQuery 具有对序列的内置支持。该函数tokenize()(如@harish.ray 所建议)返回一个序列。您也可以使用大括号和逗号自己构造一个:

let $mysequence = (1, 2, 3, 4)

序列是有序列表,因此您可以依赖它。这与从 an 返回的节点集略有不同XPath,它们通常是按文档排序的

顺便说一句:实际上,XQuery 中的所有内容要么是节点集,要么是序列。即使函数被声明为返回一个字符串或整数,您也可以将该返回值视为一个项目的序列。不需要显式强制转换,无论如何在 XQuery 中没有构造。功能喜欢fn:exists()并且fn:empty()总是有效。

于 2012-12-20T07:26:04.243 回答
2

fn:translate只是为了好玩,如果 XQuery不存在,这就是我将如何在 XQuery 中执行此操作。我认为 Michael Kay 的建议最终看起来很相似。

let $test := "Hello XQuery"
return codepoints-to-string(
  for $c in string-to-codepoints($test)
  return if ($c eq 32) then 44 else $c)

请注意,由于他指出的问题,我更改了转换:0 不是合法的代码点。所以我把空格翻译成逗号。

对于 MarkLogic,另一种选择是使用http://docs.marklogic.com/json:array及其相关函数。该json:set-item-at函数将允许以模糊的命令式编码。对这两种变体进行编码可能是一个很好的学习练习。

于 2012-12-20T18:39:58.450 回答
0

有两种方法可以做到这一点。

  • 首先,您可以使用 XmlManager.createResults() 创建一个 XmlResults 对象,然后使用 XmlResults.add() 将您的字符串添加到其中。然后,您可以使用 XmlResults 对象在 XmlQueryContext 中设置变量的值,该变量可在您的查询中使用。

    例子:

    XmlResults values = XMLManager.createResults();
    values.add(new XmlValue("value1"));
    values.add(new XmlValue("value2"));
    XmlQueryContext.setVariableValue("files", values);
    
  • 另一种方法是在 XQuery 中拆分字符串。您可以使用 tokenize() 函数执行此操作,该函数使用正则表达式来匹配字符串分隔符。

    http://www.w3.org/TR/xpath-functions/#func-tokenize

谢谢。

于 2012-12-20T06:33:23.467 回答
0

一点展望:XQuery 3.1 将为数组提供本机支持。有关详细信息,请参阅http://www.w3.org/TR/xquery-31/ 。

于 2014-08-09T22:24:46.397 回答
0

你可以像这样构造一个数组:

$myArray = tokenize('a b c d e f g', '\s')
// $myArray[3] -> c 

请注意,这个伪数组的第一个索引是 1 而不是 0!

于 2014-11-25T13:58:23.130 回答
0

由于问题“如何在 XQuery 中使用或实现数组?” 被认为是通用的(因此出现在有关该主题的搜索结果中),我想添加一个通用答案以供将来参考(使其成为社区 Wiki,以便其他人可以扩展):

正如 Christian Grün 已经暗示的那样,在XQuery 3.1中, XQuery 获得了原生数组数据类型,它是函数数据类型的子类型。

由于数组是“值的有序列表”并且 XPath/XQuery 序列也是,因此可能出现的第一个问题是:“有什么区别?” 答案很简单:一个序列不能包含另一个序列。所有序列都会自动展平。不是这样的数组,可以是数组的数组。就像序列一样,XQuery 中的数组也可以混合任何其他数据类型。

本机 XQuery 数组数据类型可以用两种方式之一表示: As[]或 via array {}。不同之处在于,在使用前一个构造函数时,逗号被视为“硬”逗号,这意味着以下数组由两个成员组成:

[ ("apples", "oranges"), "plums" ]

而以下将由三名成员组成:

array { ("apples", "oranges"), "plums" }

这意味着,花括号内的数组表达式首先被解析为一个平面序列,然后被成员化为一个数组。

由于 Array 是函数的子类型,因此可以将数组视为匿名函数,它采用单个参数,即数字索引。为了获得数组的第三个成员,名为 $foo,我们可以这样写:

$foo(3)

如果一个数组包含另一个数组作为成员,您可以将函数调用链接在一起,如下所示:

$foo(3)(5)

除了数组数据类型之外,还添加了特殊运算符,可以轻松查找数组的值。一个这样的运算符(也被新的 Map 数据类型使用)是问号后跟一个整数(或计算结果为零或多个整数的表达式)。

$foo?(3)

将再次返回数组中的第三个成员,而

$foo?(3, 6)

将返回成员 3 和 6。

使用文字整数时,可以省略括号。但是,需要使用括号来从动态表达式中形成查找索引,例如:

$foo?(3 to 6)

在这里,括号中的表达式被评估为一个整数序列,因此该表达式将返回从索引位置 3 到索引位置 6的所有成员的序列。

星号*用作通配符运算符。表达方式

$foo?*

将返回数组中所有项目的序列。同样,链接是可能的:

$foo?3?5

匹配前面的例子$foo(3)(5)

更深入的信息可以在官方规范中找到:XML Path Language (XPath) 3.1 / 3.11.2 Arrays

此外,还实现了一组特定于数组的新函数。命名空间中的这些函数resinde http://www.w3.org/2005/xpath-functions/array,通常以前缀为前缀array并且可以在此处找到引用:XPath and XQuery Functions and Operators 3.1 / 17.3 Functions that Operate on Arrays

于 2020-07-28T21:12:32.090 回答