У меня есть строковое представление некоторого XML, и я хочу запустить XQuery на нем в памяти. Я играл с Саксоном и придумал решение, но чтобы он работал, я сделал уродливую, уродливую вещь. У меня такое чувство, что из-за моего отсутствия опыта с Саксоном. Вот код, который работает:Как запустить XQuery против XML в String?
import javax.xml.transform.URIResolver;
import net.sf.saxon.Configuration;
import net.sf.saxon.s9api.*;
public class XmlTest {
public static void main(String[] args) {
try {
final String tableXml =
"<table>" +
" <columns>" +
" <column>Foo</column><column>Bar</column>" +
" </columns>" +
" <rows>" +
" <row><cell>Foo1</cell><cell>Bar1</cell></row>" +
" <row><cell>Foo2</cell><cell>Bar2</cell></row>" +
" </rows>" +
"</table>";
Configuration saxonConfig = new Configuration();
Processor processor = new Processor(saxonConfig);
XQueryCompiler xqueryCompiler = processor.newXQueryCompiler();
XQueryExecutable xqueryExec = xqueryCompiler
.compile("<result>{"
+ "doc('')/table/rows/row/cell/text()='Foo2'"
+ "}</result>");
XQueryEvaluator xqueryEval = xqueryExec.load();
xqueryEval.setSource(new SAXSource(new InputSource(
new StringReader(tableXml))));
XdmDestination destination = new XdmDestination();
xqueryEval.setDestination(destination);
// Avert your eyes!
xqueryEval.setURIResolver(new URIResolver() {
@Override
public Source resolve(String href, String base) throws TransformerException {
return new StreamSource(new StringReader(tableXml));
}
});
xqueryEval.run();
System.out.println(destination.getXdmNode());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Проблема, с которой я столкнулся, была связана с базовым URI документа XML. Поскольку это было в памяти, базового документа для ссылки не было. Я знаю, что XML всегда будет самодостаточным, поэтому я решил переопределить URIResolver
, чтобы просто передать XML, завернутый в объект типа Source
. Я знаю, что это неправильно, но это работает. Если я этого не сделаю, я получаю ошибку Content not allowed in prolog
. Из остальной части сообщения об ошибке похоже, что он пытается читать в текущем каталоге как XML-файл. Эта часть немного загадочна для меня, но я хочу учиться! Есть ли правильный способ делать то, что я хочу сделать?
Ах! Таким образом, вызов для решения URI был вызван ссылкой на 'doc (" ")'. Я изначально написал запрос без него, но добавил его как попытку исправить ошибку, которую я получал (которая теперь забыта). Он остался, потому что я чувствовал, что он улучшил ситуацию, но теперь я вижу, что это была красная селедка. Без ссылки на 'doc()' я могу удалить мою рискованную реализацию URIResolver, и все работает правильно. Спасибо, Майкл. –