[Allegro] Himmelfahrtskommando '08 : Gezeitenkräfte nutzen!
Thomas Berger
ThB at Gymel.com
Mo Mai 5 17:33:58 CEST 2008
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Lieber Herr Eversberg,
|> XSLT 2.0 etc. ist in der Tat viel maechtiger, und noch nicht
|> besonders weit verbreitet.
| Also soll man lieber 1.0 einsetzen? Und dann?
Wer und zu welchem Zweck?
Ohne jetzt ein Tutorial schreiben zu wollen, das tausendseitige
Buecher ersetzt:
XPATH ist ein Art Navigationssprache: Ich befinde mich an
einer bestimmten Stelle in einem Dokument und selektiere ueber
XPATH einen oder mehrere andere "Knoten". Das kann einfach
sein:
//record[1] - (das erste record-Element im Dokument)
oder komplizierter:
../nrw:nrwfield[@tag="100" and contains(., "Titelauflage")]
~ - diejenige Wiederholung von #100 im aktuellen Datensatz,
~ die "Titelauflage" enthaelt
es gibt aber auch Operationen mit anderen Werten:
count(preceding-sibling::record[@id=current()/@id]) = 0
- -- wahr, wenn der aktuelle Satz der erste Datensatz mit
~ gleichem id-Attribut ist (etwa bei Dublettenbereinigung)
XPATH kann ueber die sogenannten Achsen (wie etwa "preceeding-sibling"
oben kreuz und quer durch das "Dokument" navigieren, das setzt
eigentlich eine DOM-Repraesentation voraus und ist - wenn man
eine komplette _Datenbank_ als Dokument ansieht, technisch nicht
trivial. M.E. ist das die Hauptschwierigkeit beim XML-isieren
von Oracle und Konsorten gewesen.
Im Fall grosser Dokumente (etwa eine "Datei" aus vielen "Datensaetzen",
die man nicht komplett als DOM-Baum im Speicher aufbauen kann oder will,
gibt es mehrere Ansaetze, mit einem reduzierten XPATH-Satz von
Ausdruecken XPATH-aehnlich zu bleiben, aber die Dokumente SAX-artig
in "Chunks" verarbeiten zu koennen, z.B. das Perl-Modul XML::Twig
und andere Ansaetze. Da gibt es m.W. aber noch nichts so weitgehend
normiertes wie es XPATH ist.
XSLT (XSL-Transforms, wobei "XSL" wiederum fuer Xtended Stylesheet
Language steht) benutzt XPATH u.a. fuer die Selektion der Knoten,
auf denen etwas zu tun ist und fuer die Arithmetik bei
konditionellen Anweisungen (if). Es handelt sich um eine sogenannte
"funktionale" Sprache, d.h. jeder Block ist im mathematischen Sinne
eine Funktion und hat keine sog. Seiteneffekte. Insbesondere gibt
es also nichts, was im entferntesten einer globalen Variable
gleicht. Diese Philosophie ist stark gewoehnungsbeduerftig (am
Anfang ist man wirklich geneigt zu sagen, dysfunktionale Sprache),
Erfahrung in FORTH, LISP oder Haskell etc. hilft an dieser Stelle
(hatte ich aber nicht, aber immerhin hatte ich mal einen umgekehrt
polnischen Taschenrechner). XSLT ist in XML formuliert und transformiert
XML-Dokumente in andere XML-Dokumente (vorzugsweise, Text geht aber
auch). Aufgrund der Struktur der Sprache ist es hierbei theoretisch
unmoeglich, ein syntaktisch korrektes XSL-Programm zu schreiben,
das syntaktisch inkorrektes XML produziert.
|> Ohne diesen Titel jetzt zu kennen, moechte ich aber auf andere
|> Deutsche Verlagsproduktionen "Word-Referenz" etc. hinweisen,
|> die sind auch nur ueppige Paraphrasen der Online-Dokumentation,
|> auf aberhunderte von Seiten aufgeblaeht...
|>
| Was noch nicht heißt, daß die Online-Doku zum Einarbeiten reicht!
Wenn man die im Netz vorhandenen FAQ's mit beruecksichtigt:
Na sicher doch!
| was XSLT macht, mit allegro Export machen. Aber kann man alles,
| was allegro Export kann, elegant mit XSLT 1.0 machen? Dann steigen wir um.
Die Crux ist, dass die String-Funktionen von XPATH 1.0 sehr reduziert
sind, insbesondere regulaere Ausdruecke gibt es erst in XPATH 2.0.
Mit XSLT2.0 habe ich eine sehr interessante Anwendung geschrieben, die
ISBD-formatierte Ausgaben erzeugt (aus statischen XML-Exporten einer
allegro-Datenbank), insbesondere die Interpunktionsverkuerzung in
deutschen ISBD-Anwendungen und die variablen Sortieranforderungen
an geordnete Listen erfordern aber XSLT 2.0.
<thb:strunz>
<!-- so wird das dann notiert, nicht benoetigter "Glue" und
~ Pre- und Suffixe werden automatisch entfernt -->
...
~ <i:glue>. - </i:glue>
~ <i:block>
~ <xsl:call-template name="isbd-fieldorparent">
~ <xsl:with-param name="tag" select="'74 '" />
~ </xsl:call-template>
~ <i:glue> : </i:glue>
~ <xsl:call-template name="isbd-fieldorparent">
~ <xsl:with-param name="tag" select="'75 '" />
~ </xsl:call-template>
~ <i:glue xml:space="preserve"> </i:glue>
~ <i:prefix>(</i:prefix>
~ <i:block>
~ <xsl:call-template name="isbd-fieldorparent">
~ <xsl:with-param name="tag" select="'74d'" />
~ </xsl:call-template>
~ <i:glue> : </i:glue>
~ <xsl:call-template name="isbd-fieldorparent">
~ <xsl:with-param name="tag" select="'75d'" />
~ </xsl:call-template>
~ </i:block>
~ <i:suffix>)</i:suffix>
~ <i:glue>, </i:glue>
~ <xsl:call-template name="isbd-fieldorparent">
~ <xsl:with-param name="tag" select="'76'" />
~ </xsl:call-template>
~ </i:block>
...
</thb:strunz>
[Das kann natuerlich noch ad libitum in eine noch lesbarere Syntax
umformatiert werden, also etwa
<glue text=". - "/>
<field tag="74 "/>
<glue text=": "/>
<field tag="75 "/>
<glue text=" "/>
<prefix text="("/>
<field tag="74d"/>
<glue text=": "/>
<field tag="75d"/>
<suffix text=")"/>
<glue text=" ,"/>
<field tag="76"/>
oder - mit noch mehr Aufwand - als
BLOCK: x". - " #74 x": " #75 x" " p"(" #74d x": " #75d P")" x", " #76
Schaut man genauer hin, sieht man, dass ganz linear nur Kategorienummern
und zugehoerige Interpunktion aufgeschrieben werden, den Rest erledigt
ein XSLT-Programm, das hochgradig rekursiv alles einsetzt und
zum Schluss nach einfachen Regeln aufeinanderprallende Interpunktion
aufraeumt. Nachdem ich merkte, dass es funktioniert (der allegro-
Irrweg an dieser Stelle waren die bedingten /Post/fixe, mit
bedingten Praefixen kaeme man weiter), konnte ich es dann auch in der
Exportsprache nachprogrammieren [im Prinzip, die halbfertige
Parameterdatei liegt seit ueber einem Jahr hier herum und ich komme
nicht dazu, es fertig zu machen]
Die diversen XSLT 1.0-Prozessoren besitzen allerdings weitgehend
normierte Extensions, mit denen einiges moeglich ist, vor deren Einsatz
habe ich aber stets abgesehen, denn nicht jeder Processor kennt
alle Extensions. Bettet man einen XSLT-Prozessor irgendwo ein
(etwa in Perl oder a99), kann man benoetigte Extensions auch selbst
bereitstellen.
Ich bin schon in mehreren Faellen auch fuer komplexe Exporte recht
erfolgreich mit der Strategie gewesen, die zu exportierenden Daten
recht schematisch als XML aus der Datenbank zu exportieren und dann
mit XSLT weiterzuverarbeiten (insbesondere, wenn XML oder
anspruchsvolles HTML herauskommen soll), der grosse Vorteil der
Exportsprache von allegro bleibt allerdings, dass sie Datensaetze
nachladen kann.
viele Gruesse
Thomas Berger
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3-nr1 (Windows XP)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iQCVAwUBSB8o5mITJZieluOzAQL/2gP/dXWkpzVJekGJoqvjIFiq0WI7ym+88cgH
3fsw/ZQb13qY4GRZD32s4mwwhfKCIxkVDe8vjK9I9lKgcoTc8oA8h1EUqdHTfCuZ
NUA/5p9UNIASAohkJCvmsc5nL8ls7XBL4cWxWawLYPZZcTnY8eP24DpupqSB+1qr
NqXazVYbhC8=
=MavR
-----END PGP SIGNATURE-----
Mehr Informationen über die Mailingliste Allegro