I am trying to use the Saxon HE XQuery processor in a Java app to perform ad-hoc queries on XML documents.
For example:
for $x in //TestHistory[last()]/results/TestResult
where $x/status = 'TestedFailed'
return (/*/operatorId,
$x/status,
$x/expectedValue/rawValue,
$x/inputValue/rawValue)
Here I am gathering 4 values per hit.
The Java code is
Processor processor = new Processor(false);
XQueryCompiler compiler = processor.newXQueryCompiler();
XQueryExecutable exec = compiler.compile(query.getQuery());
XQueryEvaluator evaluator = exec.load();
XdmNode xmlDoc = processor.newDocumentBuilder().build(file);
evaluator.setSource(xmlDoc.asSource());
XdmValue eval = evaluator.evaluate();
int idx = 0;
int cols = 4;
int rows = eval.size/cols;
String[][] result = new String[rows][cols];
//foreach item in eval fill array
eval
contains a simple sequence of XdmItem
s which I can process - assuming that there are 4 items per row.
However, if the node inputValue/rawValue
has not been defined (which is sometimes the case) there is no corresponding XdmItem
entry and my processing approach (4 items per row) no longer works.
How can I force each requested attribute to have a corresponding XdmItem
in the result?
The "," operator does sequence concatenation, which means empty sequences get lost: the result of ("a", (), "b")
is ("a", "b")
.
One solution would be to return an array instead of a sequence:
return [/*/operatorId,
$x/status,
$x/expectedValue/rawValue,
$x/inputValue/rawValue]
You should then be able to cast the result in the Java code to XdmArray
, and convert this to a Java list of length 4 using XdmArray.asList()