2015-12-07 2 views
0

Скажем, я карту определена в XQuery, как это:Как перебирать карту в XQuery?

declare namespace map="http://www.w3.org/2005/xpath-functions/map"; 
let $x := map{'a':1, 'b':2} 

Как перебирать $x, не зная ключи?

Например:

for $key, $value in $x 
(: Some processing and output :) 
+3

(BTW, это функциональность, указанная как часть еще неизданного XQuery 3.1, а не 3.0, предположительно, вы используете один из двигателей, опережающий спецификацию). –

ответ

2

От the BaseX wiki on XQuery 3.1 features:

Тот факт, что карта является функцией пункт позволяет ему быть передан в качестве аргумента функции высшего порядка, которые ожидают в качестве одного из своих аргументов. В качестве примера, следующий запрос использует функцию высшего порядка fn:map($f, $seq) извлечь все связанные значения из карты:

let $map := map { 'foo': 42, 'bar': 'baz', 123: 456 } 
return fn:for-each(map:keys($map), $map) 

Итак, допустим, что вы хотите позвонить do-some-processing() с каждым ключом и значением :

declare namespace map="http://www.w3.org/2005/xpath-functions/map"; 
declare variable $map := map{'a':1, 'b':2}; 

declare function local:do-some-processing($key, $value) { 
    (: deciding what to put here is your problem, not mine :) 
    <key id="{$key}">{$value}</key> 
}; 

fn:for-each(
    map:keys($map), 
    function($k) { local:do-some-processing($k, $map($k)) } 
) 
+0

Что делать, если я хочу сделать что-то более сложное для ключей. См. Обновленный вопрос, чем просто вывод его значения. –

+2

. Затем вы заменили бы «$ map» (называя саму карту как функцию ключом в качестве аргумента) с функцией, которая выполняет ... любую более сложную вещь, которую вы хотите. Если вам нужен лучший ответ, вам нужно будет задать лучший вопрос. –

0

Оба моих примеров вернуть ключ со значением увеличивается на 1.

Чем больше «императив» способом было бы получить список всех ключей, петля над ними и посмотреть значения для каждого из них:

declare namespace map="http://www.w3.org/2005/xpath-functions/map"; 
let $x := map{'a':1, 'b':2} 
for $key in map:keys($x) 
return $key || $x($key) + 1 

Более элегантный, функциональный подход должен был бы использовать map:for-each на «карте» (возможно, анонимный) функции на карте (это термин в функциональном программировании при применении функции для каждого значения списка или последовательности):

declare namespace map="http://www.w3.org/2005/xpath-functions/map"; 
let $x := map{'a':1, 'b':2} 
return map:for-each($x, function($key, $value) { $key || $value + 1 }) 

в отличие от большинства других функций XQuery и функций, документации BaseX (которая обычно ограничивает к содержимому, специфичному для BaseX) предлагает довольно легко прочитать и понять ссылку и руководство по XQuery map feature.