BaseX XQJ API を使用して、Java アプリケーション内の XML ファイルに対して xquery クエリを実行しています。私がうまく構築した次の xquery は、必要な出力を生成します。
let $doc := doc("eprints")
for $i in distinct-values($doc//issn)
let $jn := $doc//paper[issn = $i]/publication
where (count(distinct-values($jn)) > 1)
return <issn num="{$i}">"{$jn}"</issn>
BaseX アプリケーションでテストしてこのクエリが機能することを確信した後、このクエリを Java コードで実装しました。
public static void main(String[] args) throws XQException{
XQDataSource ds = new BaseXXQDataSource();
ds.setProperty("serverName", "localhost");
ds.setProperty("port", "1984");
ds.setProperty("user", "xxxx");
ds.setProperty("password", "xxxxx");
ds.setProperty("databaseName", "eprints");
XQConnection conn = ds.getConnection("admin", "admin");
XQExpression xqe = conn.createExpression();
XQResultSequence result = xqe.executeQuery("let $doc := doc(\"eprints\")"+
"for $i in distinct-values($doc//issn)"+
"let $jn := $doc//paper[issn = $i]/publication"+
"where (count(distinct-values($jn)) > 1)"+
"return <issn num='{$i}'>'{jn}'</issn>"
);
}
ただし、このコードでは、$jn 変数が見つからないというエラーが発生しました: スレッド "main" javax.xml.xquery.XQQueryException での例外: [XPST0008]: 変数 $jn が未定義です。クエリを見ると、$jn が実際には for ステートメント内の let ステートメントで定義されていることがわかります。
ただし、$jn が使用された場所に $jn に割り当てられた式を直接挿入すると、コードは正しく機能します。
public static void main(String[] args) throws XQException{
XQDataSource ds = new BaseXXQDataSource();
ds.setProperty("serverName", "localhost");
ds.setProperty("port", "1984");
ds.setProperty("user", "admin");
ds.setProperty("password", "admin");
ds.setProperty("databaseName", "eprints");
XQConnection conn = ds.getConnection("admin", "admin");
XQExpression xqe = conn.createExpression();
XQResultSequence result = xqe.executeQuery("let $doc := doc(\"eprints\")"+
"for $i in distinct-values($doc//issn)"+
"where (count(distinct-values($doc//paper[issn = $i]/publication)) > 1)"+
"return <issn num='{$i}'>'{$doc//paper[issn = $i]/publication}'</issn>"
);
}
BaseX XQJ API は、for ステートメント内に let ステートメントがあるクエリを処理できないようです。エラーの原因を知っている人はいますか?