---- [[tustep:loesungen:tustep_und_xml|Zurück zur Übersichtsseite - TUSTEP und XML]] ---- ====== Integration von XQuery in TUSTEP-Workflow ====== - {{files_open:benutzericons:chmoser-lg.jpg?nolink16x16|chmoser}} chmoser\\ \\ ===== Ausgangslage ===== Beim Arbeiten mit Tustep an XML-Daten kann für spezifische Aufgaben schon einmal der Wunsch aufkommen, das Problem mit XQuery statt mit Tustep/Tuscript anzugehen. Gründe dafür könnten sein, dass sich die Aufgabe mit Tustep/Tuscript zwar lösen ließe, aber nur mit einem ungleich höheren Programmieraufwand im Vergleich zu XQuery. Weiter können - zum Beispiel im Umgang mit sehr großen Datenmengen - Performanzgründe für XQuery sprechen, das mit seinem funktionalen Zugang dem prozeduralen Zugang von Tuscript für gewisse Aufgabenstellungen (z.T. deutlich) überlegen ist.\\ Glücklicherweise offeriert Tustep die Möglichkeit, solche externen Prozesse aufzurufen, so dass XQuery-Operationen bequem in eine Tustep/Tuscript-Prozedur integriert und automatisiert aufgerufen werden können.\\ \\ ===== Lösung ===== Der Aufruf von solchen externen Prozessen geschieht mit folgender Anweisung:\\ $$ EXECUTE "pfad" "parameter" Die entsprechende Beschreibung im Tustep-Handbuch:\\ * "Unter Windows können mit der EXECUTE-Anweisung auch Programme, die in EXE- oder BAT-Dateien gespeichert sind, aufgerufen und in einem eigenen Fenster ausgeführt werden." \\ Zu beachten ist also, dass die folgend beschriebenen Lösungen nur unter Windows Gültigkeit haben. (Außerdem wird eine Java-Installation vorausgesetzt).\\ \\ Was genau rufen wir aber von Tustep aus auf? Wir rufen die Windows-Kommandozeile (cmd.exe) auf, die wiederum einen XQuery-Prozessor aufruft und diesem gewisse Parameter übergibt.\\ Als XQuery-Prozessor bietet sich [[http://sourceforge.net/projects/saxon/|Saxon]] an, der in einer freien Version (Saxon-HE home edition) zur Verfügung steht ([[http://saxon.sourceforge.net/#F9.4HE|Download hier]]). In der XML-Entwicklungsumgebung [[http://www.oxygenxml.com/|Oxygen]] ist die Saxon Enterprise Edition bereits enthalten (Datei: Oxygen-Programmordner\lib\saxon9ee.jar). Wenn man diese über die Kommandozeile außerhalb von Oxygen aufruft, stehen zwar die lizenzpflichtigen Programmteile nicht zur Verfügung, die Basis-Komponenten reichen aber für die meisten Zwecke problemlos aus.\\ \\ Beim Aufruf von Saxon können dem Programm unzählige Parameter übergeben werden. Eine Übersicht finden sich [[http://www.saxonica.com/documentation/using-xquery/commandline.html|hier]]. Im Folgenden beschränken wir uns aber auf die notwendigen Parameter. Die Syntax mit den minimalen Angaben lautet:\\ java -cp Pfad\zu\Saxon net.sf.saxon.Query -s:Pfad\zu\Eingabedatei -qs:XQuery-Statement -o:Pfad\zu\Ausgabedatei Wir brauchen also 1) den Pfad zu Saxon, 2) den Pfad zur Eingabedatei, 3) die eigentliche XQuery-Abfrage und 4) den Pfad zur Ausgabedatei.\\ \\ Beispiel:\\ java -cp "C:\Program Files\Oxygen XML Editor 15\lib\saxon9ee.jar" net.sf.saxon.Query -s:"C:\Users\CM\Documents\Tustep\beispiel\eingabe.xml" -qs:"//name" -o:"C:\Users\CM\Documents\Tustep\beispiel\ausgabe.xml" Erläuterung:\\ * Saxon befindet sich in diesem Beispiel in der Datei: C:\Program Files\Oxygen XML Editor 15\lib\saxon9ee.jar. Der Pfad steht in Anführungszeichen, weil der Pfad Leerzeichen enthält. * Die Eingabedatei heisst eingabe.xml und befindet sich im Ordner C:\Users\CM\Documents\Tustep\beispiel. * Das XQuery-Statement ist simpel: "//name" bedeutet, dass schlicht alle Elemente ausgewählt werden sollen. * Das Ergebnis der XQuery-Abfrage wird in der Datei C:\Users\CM\Documents\Tustep\beispiel\ausgabe.xml gespeichert. Falls die Datei nicht existiert, wird sie kreiert; falls sie existiert, wird sie überschrieben (auch wenn das Resultat der XQuery-Abfrage "leer" ist). \\ Nun soll das Ganze nicht direkt über die Windows-Kommandozeile aufgerufen werden, sondern aus Tustep heraus, was dann folgendermaßen aussieht (der besseren Übersicht wegen werden die Pfadangaben einer Variablen zugewiesen, sie könnten aber auch direkt angegeben werden):\\ \\ #makro $$ MODE TUSCRIPT ... SET pfadsaxon = "C:\Program Files\Oxygen XML Editor 15\lib\saxon9ee.jar" SET pfadinput = "C:\Users\CM\Documents\Tustep\beispiel\eingabe.xml" SET pfadoutput = "C:\Users\CM\Documents\Tustep\beispiel\ausgabe.xml" EXECUTE "C:\Windows\System32\cmd.exe" * DATA /C java -cp "{pfadsaxon}" net.sf.saxon.Query -s:{pfadinput} DATA -qs://name DATA -o:{pfadoutput} ... *eof \\ **Variante 1: XQuery-Statement in eine Datei auslagern**\\ Statt über den Parameter "-qs" das XQuery-Statement direkt zu übergeben, kann mit dem Parameter "-q" eine Datei angegeben werden, die die entsprechende XQuery-Abfrage enthält:\\ #makro $$ MODE TUSCRIPT ... ... EXECUTE "C:\Windows\System32\cmd.exe" * DATA /C java -cp "{pfadsaxon}" net.sf.saxon.Query -s:{pfadinput} DATA -q:C:\Users\CM\Documents\Tustep\beispiel\abfrage.xquery DATA -o:{pfadoutput} ... *eof \\ **Variante 2: Ausgabe in Zwischenablage umleiten**\\ Statt das Ergebnis in eine Datei auszugeben, kann es in die Zwischenablage kopiert werden. Dazu muss am Ende des Aufrufs statt der Ausgabedatei der Befehl ''| clip'' angegeben werden (dies ist eine Funktion der Windows-Kommandozeile, nicht des Saxon-Prozessors), also:\\ java -cp Pfad\zu\Saxon net.sf.saxon.Query -s:Pfad\zu\Eingabedatei -qs:XQuery-Statement | clip Der Inhalt der Zwischenablage kann dann in Tustep mit\\ $$ FETCH/CLIPBOARD variablenname in die Variable "variablenname" übernommen und weiterverarbeitet werden.\\ Dies zumindest in der Theorie: bei meinen Versuchen wurde die Ausgabe zwar korrekt in die Zwischenablage geleitet, allerdings konnte der Zwischenablageinhalt sodann nicht in Tustep übernommen werden.\\ \\ \\ ===== Beispiel 1 ===== Nun soll das Ganze konkret an einem "realen" Beispiel durchgespielt werden.\\ Die Eingabedaten bestehen aus Informationen zu verschiedenen Konzerten:\\ 1947-12-16 10. Volkskonzert Sturzenegger, Max Berlin Musorgskij, Modest P. "Ohne Sonne", sechs Gesänge mit Orchester Ott, Mabella Alt Musorgskij, Modest P. Persischer Tanz aus der Oper "Chowantschina" Musorgskij, Modest P. "Lieder und Tänze des Todes" für Alt und Orchester Ott, Mabella Alt Cajkovskij, Pëtr I. Sinfonie Nr. 4, in f moll, op. 36 1947-12-18 11. Volkskonzert Sturzenegger, Max Zürich Musorgskij, Modest P. "Ohne Sonne", sechs Gesänge mit Orchester Ott, Mabella Alt Musorgskij, Modest P. Persischer Tanz aus der Oper "Chowantschina" Musorgskij, Modest P. "Lieder und Tänze des Todes" für Alt und Orchester Ott, Mabella Alt Cajkovskij, Pëtr I. Sinfonie Nr. 4, in f moll, op. 36 1947-12-19 4. Jugend-Konzert Hartogs, Eduard Heidelberg Mozart, Wolfgang Amadeus Ouvertüre zu "Der Schauspieldirektor" (K.V. 486) Mendelssohn Bartholdy, Felix Violinkonzert in e-moll, op. 64 Jaques, Olivier Violine Schubert, Franz Sinfonie Nr. 5, in B-dur 1947-12-26 Nachweihnachts-Konzert Schmid, Erich Zürich Labole, P. N. "Le Flambojant", Marsch Sibelius, Jean "Finlandia", Tondichtung Scarlatti, Domenico Aus dem Konzert für Oboe und Klavier Blumer, Ernst Oboe Borodin, Aleksandr P. "Im Kloster" Dvorák, Antonín "Legende Nr. 4" Bergson, Michael "Im Norden, im Süden", Scene und Arie für Klarinette und Klavier Blumer, Fritz Klarinette Saint-Saëns, Camille Marche Héroique Eilenberg, Richard Maienfest-Walzer Silva, Cayetano Alberto "San Lorenzo", Marsch 1948-01-06 12. Volkskonzert Stoutz, Edmond de Zürich Torelli, Giuseppe Concerto a due cori, in D-dur, Nr. 32 Purcell, Henry Pavane und Chaconne, in g-moll, für Streichorchester Stravinsky, Igor Violinkonzert in D Baumgartner, Paul Violine Mozart, Wolfgang Amadeus Adagio in E-dur und Rondo in C-dur für Violine und Orchester Baumgartner, Paul Violine Haydn, Joseph Sinfonie in G-dur, Nr. 88 1948-01-13 VI. Abonnementskonzert Andreae, Volkmar Basel Cherubini, Luigi Anakreon-Ouvertüre Brun, Fritz Klavierkonzert in A-dur (1946) Hirt, Franz Josef Klavier Brahms, Johannes Sinfonie Nr. 3, in F-dur, op. 90 Die Datei heißt "konzerte.xml" und befindet sich in C:\Users\CM\Documents\Tustep\beispiel\konzerte.xml.\\ Das Ergebnis soll nach C:\Users\CM\Documents\Tustep\beispiel\konzerteneu.xml ausgegeben werden.\\ Für die Aufgabe, die es zu lösen gilt, verbleiben wir einstweilen beim Trivialen: es sollen (aus welchem Grund auch immer...) die Orte derjenigen Konzerte ausgegeben werden, in denen sowohl ein Werk von Mozart als auch von Schubert aufgeführt wurde.\\ \\ Das XQuery-Statement, das das Gewünschte leistet, lautet:\\ for $n in //konzert where $n//komponist = 'Mozart, Wolfgang Amadeus' and $n//komponist = 'Schubert, Franz' return $n/ort Aufgerufen aus Tustep heraus:\\ #makro $$ MODE TUSCRIPT SET pfadsaxon = "C:\Program Files\Oxygen XML Editor 15\lib\saxon9ee.jar" SET pfadinput = "C:\Users\CM\Documents\Tustep\beispiel\konzerte.xml" SET pfadoutput = "C:\Users\CM\Documents\Tustep\beispiel\konzerteneu.xml" EXECUTE "C:\Windows\System32\cmd.exe" * DATA /C java -cp "{pfadsaxon}" net.sf.saxon.Query -s:{pfadinput} DATA -qs:"for $n in //konzert where $n//komponist = 'Mozart, Wolfgang Amadeus' and $n//komponist = 'Schubert, Franz' return $n/ort" DATA -o:{pfadoutput} *eof Das Resultat in C:\Users\CM\Documents\Tustep\beispiel\konzerteneu.xml:\\ Heidelberg \\ \\ ===== Beispiel 2 ===== Nun ein etwas fortgeschritteneres Beispiel. Zusätzlich zur Datei konzerte.xml (siehe oben) steht nun eine Datei kritiken.xml zur Verfügung, die Daten zu Konzertkritiken enthält. Diese Daten bestehen aus den Namen der Verfasser von Konzertkritiken und deren Kritiken, die durch das ref-Attribut auf die Konzert-ids in der Datei konzerte.xml verweisen.\\ Müller, Max Nicht schlecht. Hab schon Besseres gehört. Nicht überzeugend. Meier, Fritz War super. Grottenschlecht. Fischer, Moritz Genial. Enttäuschend. Bäcker, Barbara Schön. Wunderbar. Die Aufgabe: Aus den beiden Dateien soll eine Liste erstellt werden mit dem Konzerttitel, dem Jahr, dem Ort sowie allen im jeweiligen Konzert aufgeführten individuellen Komponisten. Weiter sollen etwaige Konzertkritiken mit dem Namen des Kritikers und dem Text der Kritik dem jeweiligen Konzert beigeordnet werden. Die Konzertkritiken sollen alphabetisch nach dem Namen des Kritikers geordnet sein. Einige Elemente sollen im Laufe der Transformation umbenannt werden.\\ \\ Die XQuery dazu lautet:\\ for $ko in //konzert return {$ko/titel}{substring($ko/datum, 1,4)}{$ko/ort} {string-join(distinct-values($ko//komponist),'/')}{ for $kr in doc('file:/C:/Users/CM/Documents/Tustep/beispiel/kritiken.xml')//kritik where $ko/@id = $kr/@ref order by $kr/../name return {$kr/../name}{data($kr)}} In Tustep sodann:\\ #makro $$ MODE TUSCRIPT SET pfadsaxon = "C:\Program Files\Oxygen XML Editor 15\lib\saxon9ee.jar" SET pfadinput = "C:\Users\CM\Documents\Tustep\beispiel\konzerte.xml" SET pfadoutput = "C:\Users\CM\Documents\Tustep\beispiel\konzerteneu.xml" EXECUTE "C:\Windows\System32\cmd.exe" * DATA /C java -cp "{pfadsaxon}" net.sf.saxon.Query -s:{pfadinput} DATA -qs:"for $ko in //konzert return {$ko/titel}{substring($ko/datum, 1,4)}{$ko/ort} {string-join(distinct-values($ko//komponist),'/')} {for $kr in doc('file:/C:/Users/CM/Documents/Tustep/beispiel/kritiken.xml')//kritik where $ko/@id = $kr/@ref order by $kr/../name return {$kr/../name}{data($kr)}}" DATA -o:{pfadoutput} *eof Das Resultat:\\ 10. Volkskonzert 1947 Berlin Musorgskij, Modest P./Cajkovskij, Pëtr I. Meier, Fritz War super. Müller, Max Nicht überzeugend. 11. Volkskonzert 1947 Zürich Musorgskij, Modest P./Cajkovskij, Pëtr I. Müller, Max Hab schon Besseres gehört. 4. Jugend-Konzert 1947 Heidelberg Mozart, Wolfgang Amadeus/Mendelssohn Bartholdy, Felix/Schubert, Franz Bäcker, Barbara Schön. Nachweihnachts-Konzert 1947 Zürich Labole, P. N./Sibelius, Jean/Scarlatti, Domenico/Borodin, Aleksandr P./Dvorák, Antonín/Bergson, Michael/Saint-Saëns, Camille/Eilenberg, Richard/Silva, Cayetano Alberto Bäcker, Barbara Wunderbar. Fischer, Moritz Enttäuschend. 12. Volkskonzert 1948 Zürich Torelli, Giuseppe/Purcell, Henry/Stravinsky, Igor/Mozart, Wolfgang Amadeus/Haydn, Joseph Müller, Max Nicht schlecht. VI. Abonnementskonzert 1948 Basel Cherubini, Luigi/Brun, Fritz/Brahms, Johannes Fischer, Moritz Genial. Meier, Fritz Grottenschlecht. \\ ---- [[tustep:loesungen:tustep_und_xml|Zurück zur Übersichtsseite - TUSTEP und XML]]