Einzelne Felder in der Ausgabe zu sortieren scheint eine gewöhnliche und vor allem alltägliche Aufgabe zu sein. Ist an sich auch unproblematisch innerhalb des BizTalk-Mappers. Im Looping-Functoid gibt man die Parameter einfach in der gewünschten Reihenfolge an.
Aber das geht nur, so lange man verschiedene Eingabe-Records nicht “mischen” will.
Ein kleines Beispiel:
|
|
Natürlich sollen in der Ausgabe nach der node mit der id 1 die dazu passenden subnodes erscheinen.
Und hier wirds nun schwerer - um nicht zu sagen mit den Basis-Functoiden (ausgenommen dem Script-Functioid) unmöglich.
Wenn man einfach nur sein Looping-Functoid wie gewohnt mit den Records nodes und subnodes verbindet, erscheint in der Ausgabe (wie erwartet)
|
|
Nun - im Grunde es ist wie bei meinem Post Table Looping zusammen mit Logical Functoid - im besten Fall könnte man die SourceLink - Eigenschaft ändern und der Map-Compiler macht was draus. Tut er aber nicht :( Und leider hab ich hier noch keine Möglichkeit der XPath-Injection gefunden (nicht, dass ich nicht gesucht hätte *g*).
Das Problem ist die Art und Weise, wie der Map-Compiler das XSL-Dokument und speziell das Looping Functoid zusammensetzt.
Wenn der Eingangsparameter ein einzelnes Feld ist, dann wird dieses einfach ausgegeben. Ist es dagegen ein Record, dann wird noch ein <xsl:for-each>
-Element außenrum gesetzt (es sei denn MinOccurs und MaxOccurs des Records sind jeweils auf 1 gesetzt).
Das ist soweit noch OK, aber der Knackpunkt ist, dass jeder Eingangsparameter von den anderen getrennt wird - so kann es zu keiner Sortierung kommen.
Obiges Beispiel sieht z.B. so aus
|
|
Zwei getrennte <xsl:for-each>
-Blöcke “interdisziplinär” zu sortieren geht einfach nicht. Und das ist dann leider auch des Rätsels Lösung - es gibt keine (innerhalb des Mappings).
Naja, das wäre gelogen. Es gibt doch eine Lösung, die aber nur greift, wenn man die Elemente im Ursprungsdokument bereits sortiert hat. Dann kann man in der *.btm-Datei (als XML-Dokument öffnen) das Attribut PreserveSequenceOrder=Yes
innerhalb des mapsource-Elements angeben und die Trennung wird aufgehoben. Stattdessen werden die beiden Blöcke dann zu
|
|
In meinem Fall ist die Eingabe aber nicht korrekt sortiert und daher hilft es nur wenig - denn wie gesagt, XPath-Injection kann hier nicht verwendet werden. In einem größeren Projekt wurden bei mir sogar (bisher) unerklärliche Fehler ausgegeben, sobald die Eigenschaft auf Yes gesetzt wurde.
Zurück zum Fest: irgendwie sortieren kann man natürlich trotz allem - allerdings nur in einem weiteren Mapping. Dieses wird bestenfalls mit Hilfe einer externen XSL-Datei zu umgesetzt (oder wahlweise mit einem Scripting-Functoid und Inline XSLT). Hier folgt ein recht universelles Beispiel (d.h. es sind nur wenig Anpassungen notwendig um damit arbeiten zu können).
|
|
Vorgehensweise
- SortNodes.zip downloaden
- Anpassen (Namespace und
xsl:templates
zum Sortieren) - Speichern
- neues Mapping einfügen
- 2x das gleiche Schema auswählen und ins leere Grid klicken
- nun kann man die Custom XSL Path-Eigenschaft festlegen (mit dem Dateipfad zur obigen Datei)
- Datei durchjagen. Fertig
Nachdem das Dokument nun durch beide Mappings gelaufen ist, sieht es endlich so aus, wie es aussehen soll. Endlich ;)
|
|