Beziehung zwischen Prozessor und JAXP (Java API for XML Processing)

In den meisten Fällen werden Sie alle Ihre Anwendungen, die JAXP (Java™ API for XML Processing) verwenden, auf die aktuelle API migrieren müssen.

Die Abschnitte zur XSLT- und XPath-Verarbeitung von JAXP sind mit Bezug auf XSLT 1.0 und XPath 1.0 definiert. In JAXP sind keine Mittel für die XSLT-2.0- und XPath-2.0-Verarbeitung vorgesehen. Konkret gibt es Situationen, in denen ein XSLT-2.0- oder XPath-2.0-Prozessor ein Ergebnis erzeugen muss, das sich bei identischen Eingaben und identischem Style-Sheet oder Ausdruck von dem mit einem XSLT-1.0- oder XPath-1.0-Prozessor erzeugten Ergebnis unterscheidet. Der aktuelle Prozessor kann daher nicht mit JAXP instanziiert werden.

JAXP bietet auch keine Unterstützung für Sequenzen, XQuery 1.0 oder die vielen aktuellen Datentypen, die in XSLT 2.0, XPath 2.0 und XQuery 1.0 verfügbar sind. Darüber hinaus ist JAXP im Hinblick auf die Formate von Ein- und Ausgaben beschränkt. Alle diese Faktoren lassen JAXP wenig geeignet für die Verarbeitung von XSLT-2.0-Style-Sheets oder XPath-2.0- und XQuery-1.0-Ausdrücken erscheinen.

Die folgenden Beispiele veranschaulichen allgemeine Migrationsszenarien und zeigen, wie mit der aktuellen API Code geschrieben werden kann, der äquivalent zu Code ist, den Sie mit JAXP geschrieben haben könnten.

XSLT-Style-Sheet mit der API verarbeiten

Das folgende Beispiel veranschaulicht die Verarbeitung eines XSLT-Style-Sheets und zeigt, wie das Style-Sheet auf Eingaben angewendet wird, um eine Instanz des Interface javax.xml.transform.Result zu erzeugen.
XFactory factory = XFactory.newInstance();
XSLTExecutable style = factory.prepareXSLT(new StreamSource("style.xsl"));
style.execute(new StreamSource("input.xml"), new StreamResult(System.out));

XPath-Ausdruck mit der API verarbeiten

Das folgende Beispiel veranschaulicht die Verarbeitung eines XPath-Ausdrucks und zeigt, wie der Ausdruck auf Eingaben angewendet wird.
XFactory factory = XFactory.newInstance();
XPathExecutable pathExpr = factory.prepareXPath("/doc/child[@id='N1378']");

// Eingabe aus einer StreamSource verarbeiten
XSequenceCursor result1 = pathExpr.execute(new StreamSource("input.xml"));

// Eingabe von einem DOM-Knoten verarbeiten
XSequenceCursor result2 = pathExpr.execute(new DOMSource(node));

URI-Referenzen auflösen

Wenn Sie Referenzen auf die XSLT-Funktion document() bisher mit dem JAXP-Interface URIResolver aufgelöst haben, können Sie für diesen Zweck jetzt das Interface XSourceResolver verwenden. Zum Auflösen von Referenzen auf die Funktion document() oder fn:doc() können Sie eine Instanz des Interface XSourceResolver für eine Instanz des Interface XDynamicContext definieren. Zum Auflösen von Referenzen auf Style-Sheets, die mit xsl:import- und xsl:include-Deklarationen importiert werden, können Sie eine Instanz des Interface XSourceResolver für eine Instanz des Interface XStaticContext festlegen.

Das folgende Beispiel zeigt, wie eine Instanz des Interface XSourceResolver konfiguriert wird, die Eingabedokumente als XSLT-Style-Sheets interpretiert und diese verwendet, um die Eingabedaten zu generieren, mit denen auf die Funktion doc oder document in einem anderen XSLT-Style-Sheet verwiesen wird.
final XFactory factory = XFactory.newInstance();
XSLTExecutable style = factory.prepareXSLT(new StreamSource("style.xsl"));
XDynamicContext dContext = factory.newDynamicContext();

// Instanz einer anonymen untergeordneten Klasse erstellen und als
// XSourceResolver festlegen
dContext.setSourceResolver(new XSourceResolver() {
    // Element erstellen, das als Ausgangskontextknoten für
    // Transformationen in der Methode getSource verwendet wird
    private XItemView fDummyNode =
        factory.getItemFactory()
            .item(new StreamSource(
                new StringReader("<doc/>")));

    // Ressource als XSLT-Style-Sheet laden und auswerten, um URIs
    // aufzulösen. Ergebnis als zu verwendende Quelle zurückgeben.
    public Source getSource(String href, String base) {
        java.net.URI baseURI;
        try  { 
            // Basis-URI-Objekt abrufen
            baseURI = new java.net.URI(base);
        } catch (java.net.URISyntaxException use) {
            throw new RuntimeException(use);
        }
        // Relativer Bezug zum Basis-URI aufgelöst
        String resolvedURI = baseURI.resolve(href).toString();

        // Style-Sheet vorbereiten und ausführen
        XItemView transformResult =
            factory.prepareXSLT(new StreamSource(resolvedURI))
                .execute(fDummyNode);
        return new XItemSource(transformResult);
    }
});

XSequenceCursor result = style.execute(new StreamSource("input.xml"), dContext);

Erweiterungsfunktionen und externe Funktionen definieren

Bei der Auswertung von XPath-Ausdrücken konnten Sie mit JAXP eine Instanz des Interface XPathFunctionResolver registrieren, um die Implementierung von Erweiterungsfunktionen anzugeben, die von Ihren XPath-Ausdrücken aufgerufen werden. Der XSLT-Abschnitt von JAXP stellt keinen vergleichbaren Mechanismus bereit.

Mit der aktuellen API können Sie jedoch Erweiterungsfunktionen für eine Instanz des Interface XStaticContext deklarieren, indem Sie die erwarteten Typen der Argumente und den erwarteten Typ des Ergebnisses des Funktionsaufrufs angeben. Außerdem können Sie die Implementierung von Erweiterungsfunktionen in einer Instanz des Interface XDynamicContext registrieren. Ihr XSLT-Style-Sheet und Ihr XPath- oder XQuery-Ausdruck kann alle von Ihnen registrierten Erweiterungsfunktionen aufrufen.

Werte von Style-Sheet-Parametern und externen Variablen setzen

Mit JAXP konnten Sie die Anfangswerte von Style-Sheet-Parametern durch einen Aufruf der Methode Transformer.setParameter angeben und die Werte von Variablen für XPath-Ausdrücke durch Angabe einer Instanz des Interface XPathVariableResolver. Wenn Sie die API verwenden, können Sie Variablen mit den declareVariable()-Methoden des Interface XStaticContext deklarieren, indem Sie einen Variablennamen und den erwarteten Typ der Variablen angeben. Die Werte von Style-Sheet-Parametern, XPath-Variablen und externen XQuery-Variablen können Sie mit einer der bind()-Methoden des Interface XDynamicContext angeben.

Das folgende Beispiel zeigt, wie Sie eine Variable in einem XPath-Ausdruck verwenden können, um über die Produkt-ID nach Produkteinträgen in einem Katalog zu suchen.
XFactory factory = XFactory.newInstance();
XStaticContext sContext = factory.newStaticContext();

// XPath-Variable "query-id" im statischen Kontext deklarieren
QName queryIdVar = new QName("query-id");
sContext.declareVariable(queryIdVar, XTypeConstants.STRING_QNAME);

// XPath-Ausdruck erstellen
XItemFactory itemFactory = factory.getItemFactory();
XPathExecutable expr =
    factory.prepareXPath("/catalog/product[id eq $query-id]", sContext);

XItemView catalog = itemFactory.item(new StreamSource("catalog.xml"));
XDynamicContext dContext = factory.newDynamicContext();

// Wert der Variablen "query-id" setzen und Ausdruck mit
// diesem Variablenwert auswerten
dContext.bind(queryIdVar, "ID43785");
XSequenceCursor product1 = expr.execute(catalog, dContext);

// Wert der Variablen "query-id" setzen und Ausdruck mit
// dem neuen Variablenwert auswerten
dContext.bind(queryIdVar, "ID18574");
XSequenceCursor product2 = expr.execute(catalog, dContext);

Identitätstransformation

Eine weitere häufig verwendete JAXP-Operation ist die Identitätstransformation, die eine komfortable Vorgehensweise ist, wenn Daten in ein anderes Format transformiert werden sollen, wie es beispielsweise bei der Serialisierung einer DOM-Struktur oder beim Erzeugen einer DOM-Struktur aus SAX-Ereignissen der Fall ist. Mit der API können Sie auch Identitätstransformationen durchführen. Ein Beispiel finden Sie im Artikel XSLT-Basisoperationen ausführen.

Vorbereitungs- und Ausführungszeit konfigurieren

In JAXP werden viele Daten der Laufzeitkonfiguration für XSLT-Style-Sheets, z. B. die Werte von Style-Sheet-Parametern, URIResolver usw., direkt in den Objekten angegeben, die für Transformationen verwendet werden, nämlich in Instanzen der Interfaces Transformer und TransformerHandler. Konfigurationsdaten für die Vorbereitung von Style-Sheets und XPath-Ausdrücken werden ananlog dazu in JAXP direkt in Instanzen der Klassen TransformerFactory und XPathFactory angegen.

Mit der API können Sie Konfigurationsdaten angeben, die während der Vorbereitung eines Style-Sheets oder Ausdrucks benötigt werden, z. B. Namespacebindungen, die Typen externer Funktionen oder Variablen usw., in einer Instanz des Interface XStaticContext angeben. Alle für die Auswertung eines Style-Sheets oder Ausdrucks erforderlichen Konfigurationsdaten, z. B. die Werte von Variablen, die Einstellungen von Ausgabeparametern usw., können Sie analog dazu in einer Instanz des Interface XDynamicContext angeben, die Sie dann als Argument an die Ausführungsmethoden des Interface XExecutable und der zugehörigen untergeordneten Interfaces übergeben können.

Diese Absonderung der Konfigurationsdaten in einem separaten Objekt erhöht die Threadsicherheit der API. Ihre Anwendung eine Instanz des Interface XExecutable ohne Synchronisation für verschiedene Threads verwenden. Im Gegensatz dazu sind die Interfaces Transformer, TransformerHandler und XPathExpression von JAXP nicht threadsicher. Jeder Thread, der diese Interfaces verwendet, muss auf gemeinsam genutzte Instanzen dieser Objekte zugreifen oder für jeden Thread individuelle Kopien erstellen.

Fehler behandeln

In JAXP könnten Sie mit einer angegebenen Instanz des Interface ErrorHandler steuern, wie der Prozessor auf Fehler reagiert. In der API können Sie zu diesem Zweck eine Instanz des Interface XMessageHandler oder XStaticContext für Fehler in der Vorbereitungszeit oder des Interface XDynamicContext für Fehler der Ausführungszeit angeben.


Symbol, das den Typ des Artikels anzeigt. Konzeptartikel



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