如何在XQuery中使用或实现数组?

时间:2012-12-20 05:46:31

标签: java xml xquery marklogic

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

7 个答案:

答案 0 :(得分:6)

将示例代码转换为XQuery的问题并不是缺少对数组的支持,而是 x00 不是XML中的有效字符。如果不是这个问题,你可以用简单的函数调用表达你的查询:

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

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

当您使用XQueryXSLT等声明性语言时,请不要尝试使用相同的低级编程技术用于更原始的语言。通常有一种更直接的方式来表达问题。

答案 1 :(得分:3)

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

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

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

侧面标记:实际上,XQuery中的所有内容都是节点集序列。即使函数声明返回一个字符串或int,您也可以将返回的值视为一个项目的序列。不需要显式强制转换,无论如何在XQuery中都没有构造。 fn:exists()fn:empty()等功能始终有效。

HTH!

答案 2 :(得分:2)

只是为了好玩,如果fn:translate不存在,我将在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函数允许以模糊的命令式编码。编码这两种变化可能是一个很好的学习练习。

答案 3 :(得分:0)

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

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

    示例:

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

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

感谢。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

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

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

答案 6 :(得分:0)

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

正如ChristianGrün已经暗示的那样,通过 XQuery 3.1 ,XQuery获得了本机数组数据类型,它是函数数据类型的子类型。

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

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

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

而以下内容将由三个成员组成:

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

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

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

$foo(3)

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

$foo(3)(5)

除了数组数据类型外,还添加了特殊运算符,这些运算符使查找数组值变得容易。一个这样的运算符(也由新的Map数据类型使用)是问号,后跟一个整数(或计算为零个或多个整数的表达式)。

$foo?(3)

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

$foo?(3, 6)

将返回成员3和6。

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

$foo?(3 to 6)

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

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

$foo?*

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

$foo?3?5

$foo(3)(5)的前一个示例匹配。

更多详细信息可在官方规范中找到:XML Path Language (XPath) 3.1 / 3.11.2 Arrays

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