问题
I'm trying to execute this query:
declare variable $doc as xs:string external;
declare namespace type4="http:///de/tudarmstadt/ukp/dkpro/core/api/segmentation/type.ecore";
fn:doc($doc)//type4:Lemma/@value
within the BaseX java driver. The actual code snippet looks like this:
String queryString = "declare variable $doc as xs:string external; " +
"declare namespace type4=\"http:///de/tudarmstadt/ukp/dkpro/core/api/segmentation/type.ecore\"; " +
"fn:doc($doc)//type4:Lemma/@value";
Set<String> lemmata = new TreeSet<>();
try (ClientQuery query = this.clientSession.query(queryString))
{
query.bind("$doc", this.getUriFromDocumentId(documentId));
while (query.more())
{
String next = query.next();
logger.info(next);
lemmata.add(next);
}
return lemmata;
} catch (IOException e)
{
e.printStackTrace();
throw new QHException(e);
}
And I'm getting this exception:
[XPST0003] Unexpected end of query: 'namespace type4...'
when calling query.more()
.
Am I declaring the namespace wrong? Is there a mistake in the escaped quotes in the java code? I don't understand where xquery gets the end of query from.
The namespace is also declared in the xml documents which I am querying.
EDIT: this.getUriFromDocumentId(String documentId) just prepends the database name so that the uri is complete and actually matches the document I want to query. I check, that said document exists, before the code snippet above is executed.
回答1:
The prolog of an XQuery expression (in which you specify the declarations) is organized into two parts: Namespace declarations must be specified before variable declarations, as the first ones may be referenced by the latter ones.
In practice, this means that you need to swap the first two lines of your query.
declare namespace type4="http:///de/tudarmstadt/ukp/dkpro/core/api/segmentation/type.ecore";
declare variable $doc as xs:string external;
fn:doc($doc)//type4:Lemma/@value
Please note that this is a purely syntactical issue, it has nothing to do with the Java driver. I recommend you to use the BaseX GUI for writing queries and move the resulting queries to your driver code once they are working.
回答2:
The order of declaration matters, see https://www.w3.org/TR/xquery-31/#id-query-prolog, you need to declare the namespace first and then the variable.
回答3:
Sometimes when you're baffled by an error message then it's a good idea to try another processor. Saxon does a better job on this occasion:
Syntax error on line 2 at column 2 of file:/Users/mike/Desktop/temp/test.xq near {...ernal; declare namespace ty...}
XPST0003: Namespace declarations cannot follow variables, functions, or options
Static error on line 3 at column 27 of file:/Users/mike/Desktop/temp/test.xq near {..."; fn:doc($doc)//type4:Lemm...}
XPST0081: Namespace prefix 'type4' has not been declared
来源:https://stackoverflow.com/questions/48443237/xquery-unexpected-end-of-query-on-namespace-declaration