@ 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 ) ; } }
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 .