Использование внешних переменных в выражении XQuery

Я использую сервер базы данных BaseX с приложением Node.js. Приложение позволяет пользователю вводить несколько строк в текстовое поле, разделенных разделителем. Затем эти несколько строк должны быть запрошены в файле XML для поиска узлов, имеющих одно и то же значение. Я понятия не имею, как включить внешнюю переменную splitstring в XQuery. Вот мой код:

exports.search = function(req, res){

var string = req.body.searchBox;
string = string.toLowerCase();
var splitstring = string.split(' ');
//console.log(splitstring);
var basex = require('basex');
var log = require("../node_modules/basex/debug");

// create session
var session = new basex.Session();
basex.debug_mode = false;

// create query instance
var inputquery = 'for $node in doc("./tags.xml")/images/image return $node/source';
var query = session.query(inputquery);

query.results(log.print);

// close query instance
query.close();

// close session
session.close(); 

Я хочу реализовать что-то вроде этого:

var inputquery = 'for $node in doc("./tags.xml")/images/image where $node/tag=' + <one of the strings in splitstring> + ' return $node/source';

Можно ли сделать что-то подобное с помощью BaseX и XQuery?


person alasin    schedule 20.03.2014    source источник


Ответы (2)


Продолжая то, что уже правильно предложил Чарльз Даффи, вот пример привязки полной строки и ее токенизации в XQuery. Вы привязываете значение и определяете его как внешнее в XQuery. Разделение строки в XQuery просто выполняется с помощью fn:tokenize()

// create query instance
var inputquery = 'declare variable $string as xs:string external;' +
  'for $node in doc("./tags.xml")/images/image where $node/tag=tokenize($string, "\s") return $node/source';
var query = session.query(inputquery);
query.bind("string", string);
query.results(log.print);
query.close();
person dirkk    schedule 20.03.2014

Это абсолютно поддерживается. См. набор тестов для библиотеки node.js BaseX. .

В верхней части вашего запроса:

declare variable $variable_name external;

В вашем коде:

query.bind("variable_name", some_value);
person Charles Duffy    schedule 20.03.2014
comment
Спасибо! Но мне нужна переменная для хранения списка строковых значений, а затем выполнения запроса к этому списку (зацикливание списка, сопоставление значений и возврат узлов, если они совпадают). Можно ли этого добиться? - person alasin; 20.03.2014
comment
Опять же, собственно XQuery поддерживает его, как и BaseX в целом. Поддерживают ли привязки базы данных, специфичные для node.js, это другой вопрос. - person Charles Duffy; 20.03.2014
comment
@alasin ... конечно, вы также можете просто передать всю строку с разделителями-пробелами и разделить ее внутри своего XQuery, таким образом поднимая вопросы о возможностях привязок node.js. - person Charles Duffy; 20.03.2014
comment
Не могли бы вы рассказать мне, как это делается? Или перенаправить меня на ссылку, описывающую синтаксис или пример? Я не смог найти такой запрос. - person alasin; 20.03.2014
comment
@alasin, ссылка на функцию XPath на w3.org/TR/xpath-functions-30 — это то, с чего вы должны начать для такого рода вещей. Если поискать места, где упоминается разделение, среди них вы найдете w3.org/TR/xpath-functions-30/#func-tokenize - person Charles Duffy; 20.03.2014
comment
@alasin, ... также, вы действительно пытались передать собственный массив javascript на стороне значения вызова bind()? Если это работает, то все готово; оператор = будет действовать как объединение, когда у вас есть список на одной стороне. И если это не сработает, рассмотрите возможность подачи заявки тому, от кого вы получили привязки node.js. - person Charles Duffy; 20.03.2014