1

I am using BaseX database server with a Node.js application. The application allows a user to input multiple strings in a textfield separated by a delimiter. These multiple strings are then to be queried to the XML file to search for nodes having the same value. I don't have any idea how to include the outer variable splitstring in the XQuery. Here's my code:

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(); 

I want to implement something like this:

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

Can something like this be done using BaseX and XQuery?

alasin
  • 172
  • 3
  • 15

2 Answers2

3

This absolutely is supported. See the test suite for the node.js BaseX library.

At the top of your query:

declare variable $variable_name external;

In your code:

query.bind("variable_name", some_value);
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Thanks! But I need the variable to hold a list of string values and then perform query on that list (looping on the list, matching values and returning nodes if matched). Can that be achieved? – alasin Mar 20 '14 at 04:50
  • Again, XQuery proper supports it, as does BaseX in general. Whether the node.js-specific database bindings support it is a different question. – Charles Duffy Mar 20 '14 at 04:58
  • @alasin ...of course, you could also just pass the whole space-delimited string in, and split it inside your XQuery, thus mooting questions about the node.js bindings' capabilities. – Charles Duffy Mar 20 '14 at 05:00
  • Could you tell me how it's done? Or redirect me to a link describing the syntax or an example? I haven't been able to find such a query. – alasin Mar 20 '14 at 05:03
  • @alasin, the XPath function reference at http://www.w3.org/TR/xpath-functions-30/ is where you should start for this kind of thing. If you look for places where "split" is mentioned, among them you'll find http://www.w3.org/TR/xpath-functions-30/#func-tokenize – Charles Duffy Mar 20 '14 at 12:34
  • @alasin, ...also, did you actually *try* passing a native javascript array in on the value side of the bind() call? If it works, then you're set; the `=` operator will act as a join when you have a list on one side. And if it doesn't work, consider filing a ticket with whoever you got the node.js bindings from. – Charles Duffy Mar 20 '14 at 13:17
2

Extending on what Charles Duffy already correctly suggested, here is an example to bind the complete string and tokenize it within XQuery. You bind the value and define the value as external within XQuery. Splitting a string within XQuery is simply done by using 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();
dirkk
  • 6,160
  • 5
  • 33
  • 51