Externe Funktionen mit XQuery verwenden

Wenn Sie mit einem XQuery-Ausdruck arbeiten, der externe Funktionen verwendet, deklarieren Sie die Funktionssignaturen im XQuery-Prolog als externe Funktionen oder deklarieren Sie sie mit einer XStaticContext-Instanz. Verwenden Sie für jede Funktion eine XDynamicContext-Instanz, um eine Java-Implementierung bereitzustellen (bzw. zu binden).

Vorgehensweise

  1. Wenn Sie einen XQuery-Ausdruck erstellen, der externe Funktionen verwendet, deklarieren Sie die Funktionssignaturen im XQuery-Prolog oder mithilfe einer XStaticContext-Instanz.

    In XStaticContext deklarierte Funktionen sind nur für das Hauptmodul sichtbar. Wenn eine extern Funktionen für ein Bibliotheksmodul sichtbar sein soll, muss die Funktion im Prolog dieses Bibliotheksmoduls deklariert werden.

    Die Schnittstelle "XStaticContext" stellt zwei declareFunction-Methoden mit jeweils drei Parametern bereit, einem Parameter für den Namen, einem für den Rückgabetyp der Funktion und einem für ein Array mit den Typen der Argumente. Der Name wird immer als ein QName-Objekt angegeben. Der Typ kann jedoch ein QName oder XSequenceType sein. Der Funktionsname, der Rückgabetyp und die Argumenttypen müssen eine eindeutige Identifizierung der Funktion ermöglichen.

    Tabelle 1. declareFunction-Methoden von XStaticContext.

    In der folgenden Tabelle ist die Verwendung der einzelnen Varianten der Methode declareFunction erläutert.

    Methodensignatur Zweck
    declareFunction(QName name, QName type, QName[] argTypes) Verwendung, wenn der Rückgabewert und die Argumente der Funktion ausschließlich einzelne atomare Werte sind

    QNames für die Typen müssen auf integrierte Typen verweisen oder auf globale Typen, die in einem Schema deklariert sind, das in der für die Erstellung der XStaticContext-Instanz verwendeten XFactory-Instanz registriert ist. Wenn ein QName auf einen nicht atomaren Typ verweist, behandelt der Prozessor ihn so, als wäre er vom Typ element(*, ns:type). Hier steht ns:type für den gegebenen QName. In der Schnittstelle "XTypeConstants" sind komfortable Konstanten verfügbar, die für jeden integrierten Typ ein QName-Objekt bereitstellen.

    declareFunction(QName name, XSequenceType type, XSequenceType[] argTypes) Verwendung, wenn eines der Argumente oder der Rückgabewert der Funktion ein Knoten oder eine Sequenz atomarer Werte bzw. Knoten ist
    Der folgende XQuery-Ausdruck verwendet drei Funktionen, von denen zwei im Prolog deklariert sind.
    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>
    Ist diese Abfrage beispielsweise über das xquerySource-Source-Objekt verfügbar, bereitet der folgende Code die Abfrage vor. Die nicht in der eigentlichen Abfrage deklarierte Funktion trig:toDegrees wird in der XStaticContext-Instanz deklariert.
    // Factory erstellen
    XFactory factory = XFactory.newInstance();
    
    // Neuen statischen Kontext erstellen
    XStaticContext staticContext = factory.newStaticContext();
    
    // Namespace für die Funktionen deklarieren
    staticContext.declareNamespace("trig", "http://www.example.org/trigonometry");
    
    // QName für die Funktion trig:toDegrees erstellen
    QName toDegreesQName = new QName("http://www.example.org/trigonometry", "toDegrees");
    
    // Funktion im statischen Kontext deklarieren
    staticContext.declareFunction(toDegreesQName, XTypeConstants.DOUBLE_QNAME, new QName[]{XTypeConstants.DOUBLE_QNAME});
    
    // Ausführbares XQuery-Objekt für die Abfrage erstellen
    XQueryExecutable executable = factory.prepareXQuery(xquerySource, staticContext);
  2. Wenn Sie einen XQuery-Ausdruck ausführen, der externe Funktionen verwendet, geben Sie mit einer XDynamicContext-Instanz die Java-Methoden an, die die Funktionen implementieren, bzw. binden Sie diese Java-Methoden mit der genannten Instanz.

    Die Bindungen für externe Funktionen stehen dem Hauptmodul und allen Bibliotheksmodulen zur Verfügung, die eine Deklaration für diese Funktion in ihrem Prolog enthalten.

    Verwenden Sie die Java-Darstellung, um ein Objekt java.lang.reflect.Method für die Funktion zu erhalten. Handelt es sich bei der Methode um eine Instanzmethode, ist zum Binden dieser Funktion ein Instanzobjekt erforderlich.

    Ist für eine bei Ausführung des XQuery-Ausdrucks verwendete Funktion keine Java-Methode angegeben, tritt ein Fehler auf.

    XDynamicContext stellt zwei bindFunction-Methoden bereit. Jede dieser Methoden erfordert ein QName-Objekt, das dem Namen der Funktion entspricht, und ein Methodenobjekt, das die Java-Methode bezeichnet, die die Implementierung der Funktion zur Verfügung stellt.
    Tabelle 2. bindFunction-Methoden von XDynamicContext.

    In der folgenden Tabelle ist die Verwendung der einzelnen Varianten der bindFunction-Methoden von XDynamicContext erläutert.

    Methodenname Zweck
    bindFunction(QName qname, Method method) Verwendung, wenn eine statische Methode gebunden werden soll
    bindFunction(QName qname, Method method, Object instanceObject) Verwendung, wenn eine Instanzmethode gebunden werden soll
    Im folgenden Beispiel wird der im ersten Beispiel erstellte XQuery-Ausdruck ausgeführt. Dabei werden zunächst Methoden für die verwendeten Funktionen gebunden. In diesem Beispiel werden mit den statischen Methoden atan, sin und toDegrees der Klasse java.lang.Math die Implementierungen für die externen Funktionen bereitgestellt.
    // Neuen dynamischen Kontext erstellen
    XDynamicContext dynamicContext = factory.newDynamicContext();
    
    // Objekt java.lang.reflect.Method für die Funktion trig:toDegrees abrufen
    Method toDegreesMethod = Math.class.getMethod("toDegrees", Double.TYPE);
    
    // Funktion an den dynamischen Kontext binden
    dynamicContext.bindFunction(toDegreesQName, toDegreesMethod);
    
    // QNames für die Funktionen trig:arctan und trig:sin erstellen
    QName arctanQName = new QName("http://www.example.org/trigonometry", "arctan");
    QName sinQName = new QName("http://www.example.org/trigonometry", "sin");
    
    // java.lang.reflect.Method-Objekte für die Funktionen trig:arctan und trig:sin abrufen
    // und dann an den dynamischen Kontext binden
    Method arctanMethod = Math.class.getMethod("atan", Double.TYPE);
    Method sinMethod = Math.class.getMethod("sin", Double.TYPE);
    dynamicContext.bindFunction(arctanQName, arctanMethod);
    dynamicContext.bindFunction(sinQName, sinMethod);
    
    // XML-Eingabedokument erstellen
    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));
    
    // Abfrage ausführen
    XSequenceCursor result = executable.execute(source, dynamicContext);
     
    // Ergebnis in System.out serialisieren
    result.exportItem(new StreamResult(System.out));

Symbol, das den Typ des Artikels anzeigt. Taskartikel



Symbol für Zeitmarke Letzte Aktualisierung: 25.05.2016
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=txml_funcs_xquery
Dateiname:txml_funcs_xquery.html