Utilisation des fonctions externes avec XQuery
Quand vous utilisez une expression XQuery qui utilise des fonctions externes, déclarez les signatures de fonction dans le prologue XQuery comme fonctions externes ou à l'aide d'une instance XStaticContext. Indiquez (ou associez) une implémentation Java pour chaque fonction à l'aide d'une instance XDynamicContext.
Procédure
- Quand vous préparez une expression XQuery qui utilise des fonctions
externes, déclarez les signatures de fonction dans le prologue XQuery ou à
l'aide d'une instance XStaticContext.
Les fonctions déclarées dans XStaticContext sont visibles uniquement par le module principal. Pour qu'une fonction externe soit visible par un module de bibliothèques, il doit être déclaré dans le prologue de ce dernier.
L'interface XStaticContext possède deux méthodes declareFunction qui possèdent chacune trois paramètres : un pour le nom, un autre pour le type de fonction et un tableau pour les types des arguments. Le nom est toujours indiqué par un objet QName tandis que les types peuvent être des objets QNames ou XSequenceTypes. La fonction est identifiée de manière unique par le nom de fonction, le type de résultat et les types d'argument.
Tableau 1. Méthodes declareFunction de XStaticContext. Ce tableau décrit quand il convient d'utiliser chaque forme des méthodes declareFunction.
Signature de méthode Fonction declareFunction(QName name, QName type, QName[] argTypes) Utilisez cette méthode lorsque la valeur de retour et les arguments de la fonction correspondent tous à des valeurs atomiques uniques Le type QNames doit référencer des types intégrés ou des types globaux déclarés dans un schéma enregistré dans l'instance XFactory utilisée pour créer l'instance XStaticContext. Si un QName référence un type non atomique, le processeur le traite comme le type element(*, ns:type), où ns:type est le QName fourni. L'interface XTypeConstants propose des constantes qui fournissent un objet QName pour chaque type intégré.
declareFunction(QName name, XSequenceType type, XSequenceType[] argTypes) Utilisez cette méthode quand l'un des arguments ou la valeur de retour de la fonction correspond à un noeud ou à une séquence de valeurs atomiques ou de noeuds. L'exemple d'expression XQuery suivant utilise trois fonctions, dont deux sont déclarées dans le prologue.declare namespace xs = "http://www.w3.org/2001/XMLSchema"; declare namespace trig = "http://www.example.org/trigonometry"; declare function trig:arctan($ratio as xs:double) as xs:double external; declare function trig:sin($angle as xs:double) as xs:double external; <ramps> { for $ramp in ramps/ramp let $angleRadians := trig:arctan($ramp/height div $ramp/base) let $angle := trig:toDegrees($angleRadians) let $length := $ramp/height div trig:sin($angleRadians) return element ramp { $ramp/height, $ramp/base, element angle { $angle }, element length { $length } } } </ramps>
Supposons que cette requête est disponible via l'objet source xquerySource, le code suivant prépare la requête. La fonction non déclarée dans la requête elle-même, trig:toDegrees, est déclarée sur l'instance XStaticContext.// Create the factory XFactory factory = XFactory.newInstance(); // Create a new static context XStaticContext staticContext = factory.newStaticContext(); // Declare a namespace for the functions staticContext.declareNamespace("trig", "http://www.example.org/trigonometry"); // Create a QName for the trig:toDegrees function QName toDegreesQName = new QName("http://www.example.org/trigonometry", "toDegrees"); // Declare the function on the static context staticContext.declareFunction(toDegreesQName, XTypeConstants.DOUBLE_QNAME, new QName[]{XTypeConstants.DOUBLE_QNAME}); // Create an XQuery executable for the query XQueryExecutable executable = factory.prepareXQuery(xquerySource, staticContext);
- Pour exécuter une expression XQuery qui utilise des fonctions externes,
indiquez (ou associez) les méthodes Java qui implémentent les fonctions à
l'aide d'une instance XDynamicContext.
Les liaisons des fonctions externes seront disponibles pour le module principal et pour les modules de bibliothèque ayant une déclaration de fonction externe dans leur prologue pour cette fonction.
Utilisez une réflexion Java pour obtenir un objet java.lang.reflect.Method pour la fonction. Si la méthode est une méthode d'instanciation, un objet de méthode doit être spécifié quand vous associez cette fonction.
Une erreur est générée si vous n'indiquez pas de méthode Java pour une function utilisée lors de l'exécution de l'expression XQuery.
XDynamicContext contient deux méthodes bindFunction. Chacune requiert un objet QName correspondant au nom de la fonction et un objet Method identifiant la méthode Java qui fournira l'implémentation de la fonction.Tableau 2. Méthodes bindFunction de XDynamicContext. Ce tableau décrit quand il convient d'utiliser chaque forme des méthodes bindFunction de XDynamicContext.
Nom de la méthode Fonction bindFunction(QName qname, Method method) Utilisez cette méthode pour associer une méthode statique bindFunction(QName qname, Method method, Object instanceObject) Utilisez cette méthode pour associer une méthode d'instance L'exemple suivant montre comment exécuter l'expression XQuery préparée dans le premier exemple. Le code commence par associer des méthodes pour les fonctions qu'il utilise. Dans cet exemple, les méthodes statiques atan, sin et toDegrees de la classe java.lang.Math sont utilisées pour fournir les implémentations des fonctions externes.// Create a new dynamic context XDynamicContext dynamicContext = factory.newDynamicContext(); // Retrieve the java.lang.reflect.Method object for the trig:toDegrees function Method toDegreesMethod = Math.class.getMethod("toDegrees", Double.TYPE); // Bind the function to the dynamic context dynamicContext.bindFunction(toDegreesQName, toDegreesMethod); // Create QNames for the trig:arctan and trig:sin functions QName arctanQName = new QName("http://www.example.org/trigonometry", "arctan"); QName sinQName = new QName("http://www.example.org/trigonometry", "sin"); // Retrieve the java.lang.reflect.Method objects for the trig:arctan and trig:sin functions // then bind them to the dynamic context Method arctanMethod = Math.class.getMethod("atan", Double.TYPE); Method sinMethod = Math.class.getMethod("sin", Double.TYPE); dynamicContext.bindFunction(arctanQName, arctanMethod); dynamicContext.bindFunction(sinQName, sinMethod); // Create an XML input document String xml = "<ramps>" + "<ramp><base>4</base><height>4</height></ramp>" + "<ramp><base>4</base><height>3</height></ramp>" + "<ramp><base>10</base><height>2</height></ramp>" + "</ramps>"; StreamSource source = new StreamSource(new StringReader(xml)); // Execute the query XSequenceCursor result = executable.execute(source, dynamicContext); // Serialize the result to System.out result.exportItem(new StreamResult(System.out));
Sous-rubriques
Utilisation de fonctions externes query-declared avec XQuery
En tant qu'alternative à la liaison de méthodes Java à des fonctions dans une requête utilisant l'API, les fonctions externes Java peuvent être déclarées directement dans une requête. Des classes Java liées doivent exister sur le chemin d'accès aux classes lors de l'exécution de la requête, il s'agit de la seule configuration supplémentaire requise.


http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=txml_funcs_xquery
Nom du fichier : txml_funcs_xquery.html