Search in sources :

Example 6 with MapBasedXPathFunctionResolver

use of com.helger.xml.xpath.MapBasedXPathFunctionResolver in project ph-schematron by phax.

the class XQueryAsXPathFunctionConverter method loadXQuery.

/**
 * Load XQuery functions from an input stream. As this function is supposed to
 * work with Saxon HE, this method allows only for loading full XQuery modules
 * and not for XQuery libraries.
 *
 * @param aXQueryIS
 *        The Input Stream to read from. May not be <code>null</code>. Will be
 *        closed automatically in this method.
 * @return A non-<code>null</code> {@link MapBasedXPathFunctionResolver}
 *         containing all loaded functions.
 * @throws XPathException
 *         if the syntax of the expression is wrong, or if it references
 *         namespaces, variables, or functions that have not been declared, or
 *         any other static error is reported.
 * @throws IOException
 *         if a failure occurs reading the supplied input.
 */
@Nonnull
public MapBasedXPathFunctionResolver loadXQuery(@Nonnull @WillClose final InputStream aXQueryIS) throws XPathException, IOException {
    ValueEnforcer.notNull(aXQueryIS, "XQueryIS");
    try {
        final MapBasedXPathFunctionResolver aFunctionResolver = new MapBasedXPathFunctionResolver();
        // create a Configuration object
        final Configuration aConfiguration = new Configuration();
        final DynamicQueryContext aDynamicQueryContext = new DynamicQueryContext(aConfiguration);
        final StaticQueryContext aStaticQueryCtx = aConfiguration.newStaticQueryContext();
        // The base URI required for resolving within the XQuery
        aStaticQueryCtx.setBaseURI(m_sBaseURL);
        // null == auto detect
        final String sEncoding = null;
        final XQueryExpression exp = aStaticQueryCtx.compileQuery(aXQueryIS, sEncoding);
        final Controller aXQController = exp.newController(aDynamicQueryContext);
        // find all loaded methods and convert them to XPath functions
        final FunctionLibraryList aFuncLibList = exp.getExecutable().getFunctionLibrary();
        for (final FunctionLibrary aFuncLib : aFuncLibList.getLibraryList()) {
            // Ignore all Vendor, System etc. internal libraries
            if (aFuncLib instanceof FunctionLibraryList) {
                // This block works with Saxon HE 9.5.1-x :)
                // This is the custom function library list
                final FunctionLibraryList aRealFuncLib = (FunctionLibraryList) aFuncLib;
                for (final FunctionLibrary aNestedFuncLib : aRealFuncLib.getLibraryList()) {
                    // Currently the user functions are in ExecutableFunctionLibrary
                    if (aNestedFuncLib instanceof ExecutableFunctionLibrary)
                        for (final UserFunction aUserFunc : new IterableIterator<>(((ExecutableFunctionLibrary) aNestedFuncLib).iterateFunctions())) {
                            // Saxon 9.7 changes "getNumberOfArguments" to "getArity"
                            aFunctionResolver.addUniqueFunction(aUserFunc.getFunctionName().getNamespaceBinding().getURI(), aUserFunc.getFunctionName().getLocalPart(), aUserFunc.getArity(), new XPathFunctionFromUserFunction(aConfiguration, aXQController, aUserFunc));
                        }
                }
            } else if (aFuncLib instanceof XQueryFunctionLibrary) {
                // This block works with Saxon HE 9.6.0-x :)
                final XQueryFunctionLibrary aRealFuncLib = (XQueryFunctionLibrary) aFuncLib;
                for (final XQueryFunction aXQueryFunction : new IterableIterator<>(aRealFuncLib.getFunctionDefinitions())) {
                    // Ensure the function is compiled
                    aXQueryFunction.compile();
                    aFunctionResolver.addUniqueFunction(aXQueryFunction.getFunctionName().getNamespaceBinding().getURI(), aXQueryFunction.getFunctionName().getLocalPart(), aXQueryFunction.getNumberOfArguments(), new XPathFunctionFromUserFunction(aConfiguration, aXQController, aXQueryFunction.getUserFunction()));
                }
            }
        }
        return aFunctionResolver;
    } finally {
        StreamHelper.close(aXQueryIS);
    }
}
Also used : FunctionLibraryList(net.sf.saxon.functions.FunctionLibraryList) Configuration(net.sf.saxon.Configuration) XQueryFunctionLibrary(net.sf.saxon.query.XQueryFunctionLibrary) MapBasedXPathFunctionResolver(com.helger.xml.xpath.MapBasedXPathFunctionResolver) XQueryExpression(net.sf.saxon.query.XQueryExpression) ExecutableFunctionLibrary(net.sf.saxon.functions.ExecutableFunctionLibrary) FunctionLibrary(net.sf.saxon.functions.FunctionLibrary) XQueryFunctionLibrary(net.sf.saxon.query.XQueryFunctionLibrary) Controller(net.sf.saxon.Controller) StaticQueryContext(net.sf.saxon.query.StaticQueryContext) ExecutableFunctionLibrary(net.sf.saxon.functions.ExecutableFunctionLibrary) DynamicQueryContext(net.sf.saxon.query.DynamicQueryContext) UserFunction(net.sf.saxon.expr.instruct.UserFunction) XQueryFunction(net.sf.saxon.query.XQueryFunction) Nonnull(javax.annotation.Nonnull)

Example 7 with MapBasedXPathFunctionResolver

use of com.helger.xml.xpath.MapBasedXPathFunctionResolver in project ph-schematron by phax.

the class SchematronResourcePureTest method testResolveVariables.

@Test
public void testResolveVariables() throws SchematronException, SAXException {
    final String sTest = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n" + "<iso:schema xmlns=\"http://purl.oclc.org/dsdl/schematron\" \n" + "         xmlns:iso=\"http://purl.oclc.org/dsdl/schematron\" \n" + "         xmlns:sch=\"http://www.ascc.net/xml/schematron\"\n" + "         queryBinding='xslt2'\n" + "         schemaVersion=\"ISO19757-3\">\n" + "  <iso:title>Test ISO schematron file. Introduction mode</iso:title>\n" + "  <iso:ns prefix=\"dp\" uri=\"http://www.dpawson.co.uk/ns#\" />\n" + "  <iso:ns prefix=\"java\" uri=\"http://helger.com/schematron/test\" />\n" + "  <iso:pattern >\n" + "    <iso:title>A very simple pattern with a title</iso:title>\n" + "    <iso:rule context=\"chapter\">\n" + "      <iso:assert test=\"$title-element\">Chapter should have a title</iso:assert>\n" + "      <iso:report test=\"java:my-count(para) = 2\">\n" + "      <iso:value-of select=\"java:my-count(para)\"/> paragraphs found</iso:report>\n" + "    </iso:rule>\n" + "  </iso:pattern>\n" + "\n" + "</iso:schema>";
    // Test without variable and function resolver
    // -> an error is expected, but we don't need to log it
    assertFalse(SchematronResourcePure.fromString(sTest, StandardCharsets.UTF_8).setErrorHandler(new DoNothingPSErrorHandler()).isValidSchematron());
    // Test with variable and function resolver
    final MapBasedXPathVariableResolver aVarResolver = new MapBasedXPathVariableResolver();
    aVarResolver.addUniqueVariable("title-element", "title");
    final MapBasedXPathFunctionResolver aFunctionResolver = new MapBasedXPathFunctionResolver();
    aFunctionResolver.addUniqueFunction("http://helger.com/schematron/test", "my-count", 1, args -> {
        final List<?> aArg = (List<?>) args.get(0);
        return Integer.valueOf(aArg.size());
    });
    final Document aTestDoc = DOMReader.readXMLDOM("<?xml version='1.0'?><chapter><title /><para>First para</para><para>Second para</para></chapter>");
    final SchematronOutputType aOT = SchematronResourcePure.fromString(sTest, StandardCharsets.UTF_8).setVariableResolver(aVarResolver).setFunctionResolver(aFunctionResolver).applySchematronValidationToSVRL(aTestDoc, null);
    assertNotNull(aOT);
    assertEquals(0, SVRLHelper.getAllFailedAssertions(aOT).size());
    assertEquals(1, SVRLHelper.getAllSuccessfulReports(aOT).size());
    // Note: the text contains all whitespaces!
    assertEquals("\n      2 paragraphs found".trim(), SVRLHelper.getAllSuccessfulReports(aOT).get(0).getText());
}
Also used : DoNothingPSErrorHandler(com.helger.schematron.pure.errorhandler.DoNothingPSErrorHandler) SchematronOutputType(org.oclc.purl.dsdl.svrl.SchematronOutputType) MapBasedXPathVariableResolver(com.helger.xml.xpath.MapBasedXPathVariableResolver) MapBasedXPathFunctionResolver(com.helger.xml.xpath.MapBasedXPathFunctionResolver) List(java.util.List) Document(org.w3c.dom.Document) Test(org.junit.Test)

Aggregations

MapBasedXPathFunctionResolver (com.helger.xml.xpath.MapBasedXPathFunctionResolver)7 Test (org.junit.Test)6 SchematronOutputType (org.oclc.purl.dsdl.svrl.SchematronOutputType)5 Document (org.w3c.dom.Document)5 XQueryAsXPathFunctionConverter (com.helger.schematron.xpath.XQueryAsXPathFunctionConverter)4 CollectingPSErrorHandler (com.helger.schematron.pure.errorhandler.CollectingPSErrorHandler)2 List (java.util.List)2 ClassPathResource (com.helger.commons.io.resource.ClassPathResource)1 SchematronResourcePure (com.helger.schematron.pure.SchematronResourcePure)1 DoNothingPSErrorHandler (com.helger.schematron.pure.errorhandler.DoNothingPSErrorHandler)1 LoggingPSErrorHandler (com.helger.schematron.pure.errorhandler.LoggingPSErrorHandler)1 DOMReaderSettings (com.helger.xml.serialize.read.DOMReaderSettings)1 MapBasedXPathVariableResolver (com.helger.xml.xpath.MapBasedXPathVariableResolver)1 Nonnull (javax.annotation.Nonnull)1 Schema (javax.xml.validation.Schema)1 Configuration (net.sf.saxon.Configuration)1 Controller (net.sf.saxon.Controller)1 UserFunction (net.sf.saxon.expr.instruct.UserFunction)1 ExecutableFunctionLibrary (net.sf.saxon.functions.ExecutableFunctionLibrary)1 FunctionLibrary (net.sf.saxon.functions.FunctionLibrary)1