Verwenden Sie die integrierten XPath-Funktionen

Bei der Entwicklung eines der Online-Schulungskurse von Altova habe ich eine Liste von Büchern nach den Autoren sortiert. Dabei stellte ich fest, dass mein Autorenfeld eine Zeichenkette mit dem vollständigen Namen des Autors enthielt, sodass die Bücher nach dem ersten Buchstaben der Zeichenkette, also nach dem Vornamen des Autors, sortiert wurden. Es war nicht sinnvoll, die Sortierung in diesem Kurs zu korrigieren, aber Sie können problemlos den Nachnamen aus einer Zeichenkette extrahieren und ihn mithilfe von XPath-Funktionen als Sortierschlüssel verwenden. Wenn Sie dann die Titel der Bücher als sekundären Sortierschlüssel verwenden, stoßen Sie auf ein Problem bei Titeln, die mit "A", "An" oder "The" beginnen. Ich möchte den Titel als sekundären Sortierschlüssel verwenden, aber einen führenden bestimmten oder unbestimmten Artikel ignorieren.

Schauen wir uns an, wie wir diesen XSLT-Code erstellt haben. Dieser Artikel wurde mit der Software XMLSpy erstellt, aber die gleichen XPath-Ausdrücke können auch in MapForce oder StyleVision verwendet werden, um ähnliche Ergebnisse zu erzielen. Wir können mit einer einfachen XML-Buchliste beginnen. Wir haben 4 Bücher mit den Elementen "Autor" und "Titel".

Ein XSLT-Skript zur Erstellung einer Liste von Büchern könnte wie folgt aussehen:

Dies erzeugt die folgende Ausgabe:

Die Bücher werden in der Reihenfolge ausgegeben, in der sie in der ursprünglichen Datendatei erscheinen. Wenn wir das Element xsl:sort in die Schleife xsl:for-each einfügen, können wir die Ausgabe anders anordnen.

Dies erzeugt eine sortierte Liste, aber die Sortierung ist nicht korrekt.

Das Sortieren von Autoren als Zeichenkette führt dazu, dass "Jules Verne" vor "Mark Twain" erscheint. Ebenso erscheint "A Connecticut Yankee in King Arthur's Court" vor "Adventures of Huckleberry Finn". Wir möchten den unbestimmten Artikel "A" ignorieren, damit "Adventures of Huckleberry Finn" vor "A Connecticut Yankee in King Arthur's Court" erscheint. Wir können XPath-Ausdrücke verwenden, um die Sortierschlüssel zu extrahieren, die wir benötigen.

Bevor wir uns die Ausgabe ansehen, untersuchen wir den Code. Wir ersetzen "author" durch "reverse(tokenize(author, ' '))[1]". Die Funktion "tokenize" zerlegt den Autorennamen in einzelne Teile, wobei ein einzelnes Leerzeichen als Trennzeichen verwendet wird. So wird "Jules Verne" in "Jules" und "Verne" aufgeteilt. "Reverse" kehrt die Reihenfolge dieser Teile um, sodass wir "Verne" und "Jules" erhalten. Der Ausdruck in eckigen Klammern "[1]" wählt das erste Element aus der Liste aus, also "Verne". Dieser Wert wird für die Funktion "xsl:sort" verwendet, um die Bücher zu ordnen. Dies ist keine perfekte Lösung, aber sie funktioniert in unserem Fall. Der Titel erscheint kompliziert, aber die Logik ist einfach. Der Ausdruck "tokenize(title, ' ')[1]" extrahiert das erste Wort des Titels. Der erste "if"-Test lautet: "Ist das erste Wort des Titels das Wort 'A'?" Wenn ja, geben wir den Teil des Titels zurück, der mit dem dritten Buchstaben beginnt, wodurch "A" und das Leerzeichen entfernt werden. Wenn das erste Wort des Titels nicht "A" ist, müssen wir es erneut testen, um zu prüfen, ob das erste Wort des Titels "The" ist. Wenn ja, verwenden wir den Teil des Titels, der mit dem fünften Zeichen beginnt, wodurch "The" und ein Leerzeichen entfernt werden. Wenn beide Tests fehlschlagen, übergeben wir den Titel einfach als Sortierschlüssel. Wir könnten einen weiteren Test in unseren Code einfügen, um zu prüfen, ob das erste Wort "An" ist, aber das ist für diesen Datensatz nicht erforderlich. Durch die Ausführung dieser letzten XSLT-Transformation erhalten wir die folgende Ausgabe.

„Mark Twain“ steht jetzt vor „Jules Verne“. „Die Abenteuer des Huckleberry Finn“ erscheint vor „Der berühmte springende Frosch aus Calaveras County“ und „Ein Yankee aus Connecticut am Hofe König Arthurs“. Das Problem bei unserer Vorgehensweise bei der Autorenangabe besteht darin, dass wir möchten, dass „Jules Verne“ als „Verne, Jules“ behandelt wird, um eine korrekte Sortierung zu gewährleisten. Wenn wir also ein Buch von „Jimmy Verne“ hätten, sollen diese als unterschiedliche Autoren behandelt werden. Unser Code macht das nicht. Die Verwendung von „concat(reverse(tokenize(author, ‘ ‘))[1], reverse(tokenize(author, ‘ ‘))[2])“ würde „Jules Verne“ und „Jimmy Verne“ korrekt sortieren, aber diese Lösung funktioniert nur bei Namen mit zwei Wörtern. Wenn ein Autor einen Zusatz hat („Martin Luther King, Jr.“) oder mehrere Wörter im Namen („George Herbert Walker Bush“), würde der Code fehlschlagen. Es gibt viele Ausnahmen von den allgemeinen Regeln zur alphabetischen Sortierung von Namen, und der Code, der alle Varianten berücksichtigen würde, würde den Rahmen dieses Artikels sprengen. Was wir zeigen wollten, ist die Möglichkeit, XML-Daten dynamisch mithilfe von XPath-Ausdrücken zu manipulieren. Wir haben nicht immer die vollständige Kontrolle über das Format unserer Datenquellen, aber mithilfe der Leistungsfähigkeit von XPath-Ausdrücken können wir die Daten in das Format umwandeln, das wir benötigen. Eine Kopie der in diesen Beispielen verwendeten Dateien ist hier verfügbar.