Project

Profile

Help

Support #6039 ยป TestXQueryCompiler.java

Saxonica unit tests for XQueryCompiler - Michael Kay, 2023-05-15 16:24

 
package s9apitest;

import com.saxonica.config.EnterpriseConfiguration;
import jaxptest.ConfigTest;
import net.sf.saxon.Configuration;
import net.sf.saxon.dom.DOMNodeWrapper;
import net.sf.saxon.dom.DocumentWrapper;
import net.sf.saxon.expr.Literal;
import net.sf.saxon.expr.instruct.GlobalVariable;
import net.sf.saxon.lib.Feature;
import net.sf.saxon.om.NodeInfo;
import net.sf.saxon.query.DynamicQueryContext;
import net.sf.saxon.s9api.*;
import org.junit.jupiter.api.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.TransformerException;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

/**
* JUnit tests for the s9api XQueryCompiler
*/
public class TestXQueryCompiler {
private final ConfigTest configTest = new ConfigTest();
@Test
public void testModuleUriResolverNoBaseUri() {
try {
Processor p = new Processor(false);
XQueryCompiler c = p.newXQueryCompiler();
c.setModuleURIResolver((moduleURI, baseURI, locations) -> {
String module = "";
if (moduleURI.equals("b.uri")) {
module = "module namespace b='b.uri'; import module namespace c = 'c.uri' at 'c.xq'; " +
"declare variable $b:b := $c:c;";
} else if (moduleURI.equals("c.uri")) {
module = "module namespace c='c.uri';" +
"declare variable $c:c := 42;";
}
StringReader sr = new StringReader(module);
StreamSource ss = new StreamSource();
ss.setReader(sr); // don't set the base URI
return new StreamSource[]{ss};
});
XQueryExecutable exec = c.compile("import module namespace b = 'b.uri' at 'b.xq'; $b:b");
XdmValue val = exec.load().evaluate();
assertEquals(42L, ((XdmAtomicValue) val).getLongValue());
} catch (SaxonApiException e) {
fail(e.getMessage());
}
}

@Test
public void testDefaultNamespace() {
try {
Processor p = new Processor(false);
DocumentBuilder b = p.newDocumentBuilder();
XdmNode foo = b.build(new StreamSource(new StringReader("<foo xmlns='http://one.uri/'><bar/></foo>")));
XQueryCompiler c = p.newXQueryCompiler();
c.declareNamespace("", "http://one.uri/");
XQueryEvaluator eval = c.compile("/foo").load();
eval.setContextItem(foo);
XdmValue val = eval.evaluate();
assertEquals(1, val.size());
} catch (SaxonApiException e) {
fail(e.getMessage());
}

}

@Test
public void testReusability() {
// Test that the XQuery compiler can compile two queries without interference
try {
Processor p = new Processor(false);
DocumentBuilder b = p.newDocumentBuilder();
XdmNode foo = b.build(new StreamSource(new StringReader(
"<foo xmlns='http://one.uri/'><bar xmlns='http://two.uri'>12</bar></foo>")));
XQueryCompiler c = p.newXQueryCompiler();
c.declareNamespace("", "http://one.uri/");
XQueryExecutable q1 = c.compile("declare variable $p as xs:boolean external; exists(/foo) = $p");
c.declareNamespace("", "http://two.uri");
XQueryExecutable q2 = c.compile("declare variable $p as xs:integer external; /*/bar + $p");
XQueryEvaluator e1 = q1.load();
XQueryEvaluator e2 = q2.load();
e1.setContextItem(foo);
e1.setExternalVariable(new QName("p"), new XdmAtomicValue(true));
XdmValue val = e1.evaluate();
assertTrue(((XdmAtomicValue) val).getBooleanValue());
e2.setContextItem(foo);
e2.setExternalVariable(new QName("p"), new XdmAtomicValue(6));
val = e2.evaluate();
assertEquals(18, ((XdmAtomicValue) val).getLongValue());
} catch (SaxonApiException e) {
fail(e.getMessage());
}

}

@Test
public void testMultithreading() {
// Test that the XQuery compiler can compile many queries concurrently without interference
try {
Processor p = new Processor(false);
DocumentBuilder b = p.newDocumentBuilder();
final XdmNode foo = b.build(new StreamSource(new StringReader(
"<foo xmlns='http://one.uri/'><bar xmlns='http://two.uri/'>12</bar></foo>")));
final XQueryCompiler c = p.newXQueryCompiler();
c.declareNamespace("a", "http://one.uri/");
c.declareNamespace("b", "http://two.uri/");
Runnable task = () -> {
try {
XQueryEvaluator q = c.compile("a:foo/b:bar + a:foo/b:bar + a:foo/b:bar + a:foo/b:bar").load();
q.setContextItem(foo);
XdmAtomicValue v = (XdmAtomicValue)q.evaluateSingle();
assertEquals("48", v.toString(), "ok");
} catch (Exception e) {
e.printStackTrace();
fail();
}
};
for (int i = 0; i < 100; i++) {
task.run();
}
} catch (SaxonApiException e) {
fail(e.getMessage());
}

}



@Test
public void testSeparateCompilation() {
try {
Processor proc = new Processor(true);
XQueryCompiler comp = proc.newXQueryCompiler();
comp.compileLibrary("module namespace m='http://www.example.com/module-one'; " +
"declare function m:add($a as xs:integer, $b as xs:integer) as xs:integer { $a + $b };" +
"declare variable $m:ten as xs:integer := 10;");
String q1 = "import module namespace m='http://www.example.com/module-one'; m:add(2,2)";
XQueryEvaluator ev = comp.compile(q1).load();
assertEquals("4", ev.evaluate().toString(), "2+2");
String q2 = "import module namespace m='http://www.example.com/module-one'; m:add($m:ten,5)";
ev = comp.compile(q2).load();
assertEquals("15", ev.evaluate().toString(), "10+5");
} catch (SaxonApiException e) {
fail(e.getMessage());
}
}

@Test
public void testSeparateCompilationNested() {
try {
Processor proc = new Processor(true);
XQueryCompiler comp = proc.newXQueryCompiler();
comp.compileLibrary(new StringReader("module namespace m1='http://www.example.com/module-one'; " +
"declare function m1:add($a as xs:integer, $b as xs:integer) as xs:integer { $a + $b };" +
"declare variable $m1:ten as xs:integer := 10;"));
comp.compileLibrary("module namespace m2='http://www.example.com/module-two'; " +
"import module namespace m1='http://www.example.com/module-one';" +
"declare function m2:add($a as xs:integer, $b as xs:integer) as xs:integer { m1:add($a, $b) };" +
"declare variable $m2:ten as xs:integer := $m1:ten;");
String q1 = "import module namespace m2='http://www.example.com/module-two'; m2:add($m2:ten,2)";
XQueryEvaluator ev = comp.compile(q1).load();
assertEquals("12", ev.evaluate().toString(), "10+2");
String q2 = "import module namespace m1='http://www.example.com/module-one'; m1:add($m1:ten,5)";
ev = comp.compile(q2).load();
assertEquals("15", ev.evaluate().toString(), "10+5");
} catch (SaxonApiException e) {
fail(e.getMessage());
}
}

@Test
public void testSeparateCompilationImportFromNonSeparatelyCompiledLibraryModule() {
try {
Processor proc = new Processor(true);
XQueryCompiler comp = proc.newXQueryCompiler();
// try {
// comp.setBaseURI(new URI("http://www.example.com/module-one"));
// } catch (URISyntaxException e) {
// //
// }
comp.compileLibrary(new StringReader("module namespace m1='http://www.example.com/module-one'; " +
"declare function m1:add($a as xs:integer, $b as xs:integer) as xs:integer { $a + $b };" +
"declare variable $m1:ten as xs:integer := 10;"));
final String m2 = "module namespace m2='http://www.example.com/module-two'; " +
"import module namespace m1='http://www.example.com/module-one';" +
"declare function m2:add($a as xs:integer, $b as xs:integer) as xs:integer { m1:add($a, $b) };" +
"declare variable $m2:ten as xs:integer := $m1:ten;";
String q1 = "import module namespace m2='http://www.example.com/module-two'; m2:add($m2:ten,2)";
comp.setModuleURIResolver((moduleURI, baseURI, locations) -> {
if (moduleURI.equals("http://www.example.com/module-two")) {
return new StreamSource[]{new StreamSource(new StringReader(m2), "http://www.example.com/module-two")};
} else {
return null;
}
});
XQueryEvaluator ev = comp.compile(q1).load();
assertEquals("12", ev.evaluate().toString(), "10+2");
String q2 = "import module namespace m1='http://www.example.com/module-one'; m1:add($m1:ten,5)";
ev = comp.compile(q2).load();
assertEquals("15", ev.evaluate().toString(), "10+5");
} catch (SaxonApiException e) {
fail(e.getMessage());
}
}

@Test
public void testSeparateCompilationDiamond() {
try {
Processor proc = new Processor(true);
proc.setConfigurationProperty(Feature.GENERATE_BYTE_CODE, false);
XQueryCompiler comp = proc.newXQueryCompiler();

try {
comp.setBaseURI(new URI("http://www.example.com/module-one"));
} catch (URISyntaxException e) {
//
}
comp.compileLibrary(new StringReader("module namespace m1='http://www.example.com/module-one'; " +
"declare function m1:add($a as xs:integer, $b as xs:integer) as xs:integer { $a + $b };"));
try {
comp.setBaseURI(new URI("http://www.example.com/module-two"));
} catch (URISyntaxException e) {
//
}
comp.compileLibrary("module namespace m2='http://www.example.com/module-two'; " +
"import module namespace m1='http://www.example.com/module-one';" +
"declare function m2:subtract($a as xs:integer, $b as xs:integer) as xs:integer { m1:add($a, -$b) };");
try {
comp.setBaseURI(new URI("http://www.example.com/module-three"));
} catch (URISyntaxException e) {
//
}
comp.compileLibrary("module namespace m3='http://www.example.com/module-three'; " +
"import module namespace m1='http://www.example.com/module-one';" +
"declare function m3:times($a as xs:integer, $b as xs:integer) as xs:integer { " +
" if ($b=1) then $a else m1:add($a, m3:times($a, $b - 1)) };");
String q1 = "import module namespace m2='http://www.example.com/module-two'; " +
"import module namespace m3='http://www.example.com/module-three';" +
"m2:subtract(m3:times(4,2),1)";
XQueryEvaluator ev = comp.compile(q1).load();
assertEquals("7", "7", ev.evaluate().toString());
String q2 = "import module namespace m2='http://www.example.com/module-two'; " +
"import module namespace m3='http://www.example.com/module-three';" +
"m2:subtract(m3:times(5,2),1)";
XQueryEvaluator ev2 = comp.compile(q2).load();
assertEquals("9", "9", ev2.evaluate().toString());
} catch (SaxonApiException e) {
fail(e.getMessage());
}
}


@Test
public void testSeparateCompilationDiamondWithVariables() {
try {
Processor proc = new Processor(true);
XQueryCompiler comp = proc.newXQueryCompiler();

comp.compileLibrary(new StringReader("module namespace m1='http://www.example.com/module-one'; " +
"declare function m1:add($a as xs:integer, $b as xs:integer) as xs:integer { $a + $b };" +
"declare variable $m1:ten := 10;"
));

comp.compileLibrary("module namespace m2='http://www.example.com/module-two'; " +
"import module namespace m1='http://www.example.com/module-one';" +
"declare function m2:subtract($a as xs:integer, $b as xs:integer) as xs:integer { m1:add($a, -$b) };" +
"declare variable $m2:eleven := $m1:ten + 1;");

comp.compileLibrary("module namespace m3='http://www.example.com/module-three'; " +
"import module namespace m1='http://www.example.com/module-one';" +
"declare function m3:times($a as xs:integer, $b as xs:integer) as xs:integer { " +
" if ($b=1) then $a else m1:add($a, m3:times($a, $b - 1)) };" +
"declare variable $m3:twelve := $m1:ten + 2;");

String q1 = "import module namespace m2='http://www.example.com/module-two'; " +
"import module namespace m3='http://www.example.com/module-three';" +
"m2:subtract(m3:times(4,2),1) + $m3:twelve";
XQueryEvaluator ev = comp.compile(q1).load();
assertEquals("19", "19", ev.evaluate().toString());
String q2 = "import module namespace m2='http://www.example.com/module-two'; " +
"import module namespace m3='http://www.example.com/module-three';" +
"m2:subtract(m3:times(5,2),1) + $m2:eleven";
XQueryEvaluator ev2 = comp.compile(q2).load();
assertEquals("20", "20", ev2.evaluate().toString());
} catch (SaxonApiException e) {
fail(e.getMessage());
}
}

@Test
public void testSeparateCompilationForwardsRef() {
try {
Processor proc = new Processor(true);
XQueryCompiler comp = proc.newXQueryCompiler();
comp.compileLibrary(
"module namespace lib = 'http://example.com/library';" +
"declare function lib:foo($a) { lib:bar($a) };" +
"declare function lib:bar($b) { concat($b, '!') };");

XQueryExecutable exp = comp.compile(
"import module namespace lib = 'http://example.com/library';"
+ "\nlib:foo('a')"
);

XdmItem result = exp.load().evaluateSingle();
assertEquals("a!", result.getStringValue());

} catch (SaxonApiException err) {
fail(err.getMessage());
}
}


/**
* s9api query/transformation pipeline
*/

@Test
public void testPipeline() {
try {
Processor proc = new Processor(false);
XsltCompiler tComp = proc.newXsltCompiler();
XQueryCompiler qComp = proc.newXQueryCompiler();
StringWriter sw = new StringWriter();
Serializer out = proc.newSerializer(sw);
String xsl = "<xsl:stylesheet version='2.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>" +
"<xsl:template match='/'><t><xsl:copy-of select='.'/></t></xsl:template>" +
"</xsl:stylesheet>";
String q = "document { <q>{.}</q> }";
String xml = "<z/>";
XdmNode in = proc.newDocumentBuilder().build(new StreamSource(new StringReader(xml)));
XsltTransformer stage1 = tComp.compile(new StreamSource(new StringReader(xsl))).load();
XQueryEvaluator stage2 = qComp.compile(q).load();
XsltTransformer stage3 = tComp.compile(new StreamSource(new StringReader(xsl))).load();
XQueryEvaluator stage4 = qComp.compile(q).load();
XsltTransformer stage5 = tComp.compile(new StreamSource(new StringReader(xsl))).load();
stage1.setDestination(stage2);
stage2.setDestination(stage3);
stage3.setDestination(stage4);
stage4.setDestination(stage5);
stage5.setDestination(out);
stage1.setInitialContextNode(in);
stage1.transform();
assertTrue(sw.toString().contains("<t><q><t><q><t><z/></t></q></t></q></t>"), "output");

} catch (SaxonApiException err) {
err.printStackTrace();
fail(err.getMessage());
}
}


@Test
public void testErrorListener() {
final List<TransformerException> errors = new ArrayList<>();
final List<TransformerException> fatalErrors = new ArrayList<>();
final List<TransformerException> warnings = new ArrayList<>();
try {
Processor p = new Processor(true);
XQueryCompiler c = p.newXQueryCompiler();

c.setErrorListener(new ErrorListener() {
@Override
public void error(TransformerException exception) {
errors.add(exception);
}

@Override
public void warning(TransformerException exception) {
warnings.add(exception);
}

@Override
public void fatalError(TransformerException exception) {
fatalErrors.add(exception);
}
});
XQueryEvaluator eval = c.compile("$x + /undec:y = ").load();
StringWriter sw = new StringWriter();
Serializer out = p.newSerializer(sw);
out.setOutputProperty(Serializer.Property.OMIT_XML_DECLARATION, "yes");
StreamSource in = new StreamSource(new File(configTest.getDataDir() + "books.xml"));
eval.runStreamed(in, out);
fail("unexpected success");
} catch (SaxonApiException e) {
assertEquals(0, errors.size(), "errors");
assertEquals(1, fatalErrors.size(), "fatalErrors");
assertEquals(0, warnings.size(), "warnings");
}
}


@Test
public void testIssue2111() {
try {
final Configuration configuration = new Configuration();
configuration.setConfigurationProperty(Feature.XQUERY_VERSION, "1.0");
configuration.setModuleURIResolver((moduleURI, baseURI, locations) -> {
StringReader reader = new StringReader("module namespace x='x'; declare variable $x:x := 'x';");
StreamSource module = new StreamSource(reader);
module.setSystemId(moduleURI);
return new StreamSource[]{module};
});
Processor processor = new Processor(configuration);
XQueryCompiler xqueryCompiler = processor.newXQueryCompiler();
xqueryCompiler.setBaseURI(new File(".").toURI());
XQueryExecutable executable = xqueryCompiler.compile("import module namespace x='x'; $x:x\n");
executable.load().run(processor.newSerializer(System.out));

} catch (SaxonApiException err) {
fail();
}

}

@Test
public void testAbleToCompileWithCompileLibraryMethod() throws SaxonApiException {
// See bug 2429
XQueryCompiler compiler = new Processor(true).newXQueryCompiler();
final String main = "" +
"module namespace main = \"main_mod.xq\";\n" +
"import module namespace vi_imp = \"imported_mod.xq\";\n" +
"declare %private variable $main:variableThatIsInstantiatedTwice as xs:integer := 123;";

compiler.setModuleURIResolver((moduleURI, baseURI, locations) -> {
String module = "";
if (moduleURI.equals("imported_mod.xq")) {
module =
"module namespace vi_imp = \"imported_mod.xq\";\n" +
"import module namespace vi_main = \"main_mod.xq\" at \"file:///nowhere/variable_issue_main.xq\";";
} else if (moduleURI.equals("main_mod.xq")) {
module = main;
}
return new StreamSource[]{new StreamSource(new StringReader(module), moduleURI)};
});
// try {
// compiler.setBaseURI(new URI("file:///nowhere/variable_issue_main.xq"));
// } catch (URISyntaxException e) {
// fail(e.getMessage());
// }
compiler.compileLibrary(main);
}

@Test
public void testGlobalVariableLineNumber() {
try {
String query = "declare namespace c = 'c.uri';\n\n\ndeclare variable $foo := 3;\n$foo";
Processor p = new Processor(false);
XQueryCompiler c = p.newXQueryCompiler();
XQueryExecutable q = c.compile(query);
Iterator<GlobalVariable> vars = q.getUnderlyingCompiledQuery().getMainModule().getModuleVariables();
int count = 0;
while (vars.hasNext()) {
GlobalVariable v = vars.next();
assertEquals(4, v.getLineNumber());
count++;
}
assertEquals(1, count);
} catch (SaxonApiException e) {
fail(e.getMessage());
}

}


@Test
public void testPreEvaluateDocFunction() {
// Bug 2963
String badQuery = "doc('http://example.com/bad')";
String goodQuery = "doc('http://example.com/good')";
Processor p = new Processor(false);
XQueryCompiler c = p.newXQueryCompiler();
final List<String> counter = new ArrayList<>();
p.getUnderlyingConfiguration().setResourceResolver(request -> {
switch (request.relativeUri) {
case "http://example.com/bad":
String badXml = "<bad>";
counter.add(request.relativeUri);
return new StreamSource(new StringReader(badXml));
case "http://example.com/good":
String goodXml = "<good/>";
counter.add(request.relativeUri);
return new StreamSource(new StringReader(goodXml));
default:
return null;
}
});
p.setConfigurationProperty(Feature.PRE_EVALUATE_DOC_FUNCTION, false);
XQueryExecutable q = null;
try {
q = c.compile(badQuery);
} catch (Exception err) {
fail("Compilation should not fail");
err.printStackTrace();
}
assertEquals(0, counter.size(), "URI not accessed");
p.setConfigurationProperty(Feature.PRE_EVALUATE_DOC_FUNCTION, true);
try {
q = c.compile(goodQuery);
assertTrue(counter.size() > 0, "URI accessed");
assertTrue(q.getUnderlyingCompiledQuery().getExpression() instanceof Literal, "Compiled to Literal");
assertTrue(((Literal) q.getUnderlyingCompiledQuery().getExpression()).getGroundedValue().head() instanceof NodeInfo, "Compiled to NodeInfo");
} catch (Exception err) {
fail("Compilation should not fail");
}
try {
XdmValue result = q.load().evaluateSingle();
assertTrue(result instanceof XdmNode);
} catch (Exception err) {
fail("Execution should not fail");
err.printStackTrace();
}

}

private static class MyErrorListener implements ErrorListener {
public final List<TransformerException> warnings = new ArrayList<>();
public final List<TransformerException> errors = new ArrayList<>();
public final List<TransformerException> fatalErrors = new ArrayList<>();

@Override
public void warning(TransformerException exception) {
warnings.add(exception);
}

@Override
public void error(TransformerException exception) {
errors.add(exception);
}

@Override
public void fatalError(TransformerException exception) {
fatalErrors.add(exception);
}
}

@Test
public void testXQueryValidationErrorReporting() {
// Bug 3123
MyErrorListener listener = new MyErrorListener();
try {
Processor p = new Processor(true);
DocumentBuilder b = p.newDocumentBuilder();
XdmNode foo = b.build(new StreamSource(new StringReader("<foo xmlns='http://one.uri/'><bar/></foo>")));
XQueryCompiler c = p.newXQueryCompiler();
c.declareNamespace("", "http://one.uri/");
XQueryEvaluator eval = c.compile("validate strict{.}").load();

eval.setErrorListener(listener);
eval.setContextItem(foo);
XdmValue val = eval.evaluate();
fail();
} catch (SaxonApiException e) {
assertEquals(0, listener.errors.size());
assertTrue(listener.fatalErrors.size() > 0);
}
}

@Test
public void testDiagnosticsOnAtomizationFailure() {
// Bug 4086
try {
Processor p = new Processor(true);
DocumentBuilder b = p.newDocumentBuilder();
XdmNode foo = b.build(new StreamSource(new StringReader("<foo xmlns='http://one.uri/'><bar/></foo>")));
XQueryCompiler c = p.newXQueryCompiler();
c.declareNamespace("", "http://one.uri/");
XQueryEvaluator eval = c.compile("declare function local:x($n as node(), $a as xs:integer){$a+string-length(name($n))}; local:x(<z/>, map{'x':2})").load();
XdmValue val = eval.evaluate();
fail();
} catch (SaxonApiException e) {
System.err.println(e);
}
}

@Test
public void testXQueryOptimizationWithTracing() {
// Bug 3497

String query = "declare variable $root := <root><text>AAA</text></root>;" +
"declare function local:foo($root) {$root/text};" +
"local:foo($root)";

try {
Processor p = new Processor(true);
XQueryCompiler c = p.newXQueryCompiler();
c.setCompileWithTracing(true);
XQueryEvaluator eval = c.compile(query).load();
XdmValue val = eval.evaluate();
} catch (SaxonApiException e) {
e.printStackTrace();
fail();
}
}

@Test
public void testBug5680() {
try {
Configuration c = new EnterpriseConfiguration();

Processor processor = new Processor(c);
XQueryCompiler qc = processor.newXQueryCompiler();
XQueryExecutable exp = qc.compile(
"declare function local:f($v as element()?) { " +
" $v/node()" +
"};" +
"local:f(//inner)");

XQueryEvaluator ev = exp.load();
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
docFactory.setNamespaceAware(true);
javax.xml.parsers.DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("test");
Element inner = doc.createElement("inner");
//rootElement.appendChild(inner); //uncomment to pass the test
doc.appendChild(rootElement);

DynamicQueryContext dynamicContext = ev.getUnderlyingQueryContext();
DocumentWrapper docWrapper = new DocumentWrapper(doc, doc.getBaseURI(), dynamicContext.getConfiguration());
DOMNodeWrapper context = docWrapper.wrap(doc.getDocumentElement());
dynamicContext.setContextItem(context);

for (int i = 1; i < 200; i++) //fails on 100 iteration
{
System.out.println(i);
XdmSequenceIterator<XdmItem> result = ev.iterator();
}
} catch (SaxonApiException e) {
e.printStackTrace();
fail();
} catch (SaxonApiUncheckedException e) {
e.printStackTrace();
fail();
} catch (ParserConfigurationException e) {
e.printStackTrace();
fail();
}
}


}
    (1-1/1)