[gelöst] XML-Datei mit wechselnden Tags

26. März 2007 21:39

Hallo,

ich habe folgendes Problem mit XML-Ports:

Ein Kunde bekommt verschiedene Nachrichten per TCP/IP (Socket Bus Adapter-Automation). Es gibt genau eine Codeunit, die diese Messages empfängt, da sie das Receive-Event der Communication Component (version 2)-Automation abfängt. Diese Codeunit soll jetzt anhand des Inhalts der XML-Datei entscheiden, welcher XML-Port zur Verarbeitung herangezogen wird. Dazu sind die ersten 3 Tags in jeder xml-Datei mit "MessageType" "Subtype" und "Sender" fest vorgegeben.
Ich wollte jetzt einen "General Info"-XML-Port schreiben, der nur diese 3 Tags abfragt, mit einer Tabelle vergleicht, in der diese Informationen mit einer zugehörigen Objekt-Nr. hinterlegt sind, und dementsprechend den richtigen XML-Port aufruft.
Jetzt habe ich aber das Problem, dass im XML-File natürlich mehr Tags stehen, als diese drei, und sobald der 4. Tag kommt (der sich von Messagetyp zu Messagetyp unterscheidet) bricht der XML-Port - zum Beispiel bei Bestellungen - mit der Meldung "Das Element <Order> wurde nicht erwartet" ab.
Kann ich dem XML-Port irgendwie sagen, dass er die Tags nach <Sender> überlesen soll? CurrXMLPort.SKIP, .QUIT und .BREAK haben nicht funktioniert ...

... ratlos ...
Dirk
Zuletzt geändert von IT-Co+De am 27. März 2007 13:13, insgesamt 1-mal geändert.

26. März 2007 23:39

Nein, die einzige Chance ist, den Stream vorher mit Stringfunktionen zu untersuchen und darauf hin weiterzuleiten, oder du baust als eierlegende Wollmichsau einen XMLPort, der alle Tags in der richtigen Reihenfolge angibt, dazu wäre es sinnvoll die eigentlichen Nutzdaten so in die ersten 3 Tags einzuschachteln, dass du bei den Kopftags einfach MinOccurs=0 als Property festlegst und er dann zum nächsten Header-Tag springt, je nachdem wieviele Kombinationen nötig sind, artet das aber in Arbeit aus.
Ich habe das mal gemacht, für den Import von Artikel-XML-Dateien, die die Stücklistenkomponenten verschachtelt darstellen, wobei jede Komponente den komplette Tagsatz des Artikels beinhaltet und die Verschachtelungstiefe bis zu 15 Ebenen laut Definition in Exact Pro sein darf. Da bei den zur Konvertierungs anstehenden Daten aber keine so hohe Schachtelung auftrat hab ich bei 9 Ebenen aufgehört.....

27. März 2007 12:49

Hallo Dirk,

ich würde die XML-Datei in ein XML-Dokument laden und dann untersuchen. Das würde dann ungefähr so aussehen:

Code:
Variablenname     Typ                Subtyp
XMLDoc            Automation         'Microsoft XML, v3.0'.DOMDocument
XMLNode           Automation         'Microsoft XML, v3.0'.IXMLDOMNode
---------------


XMLDoc.loadXML(xmlString);
XMLNode := RootNode.selectSingleNode('/MessageType');
IF NOT ISCLEAR(XMLNode) THEN BEGIN
  CASE XMLNode.nodeValue OF
    'TYP1' :
      StarteXMLPort1();
    'TYP2' :
      StarteXMLPort2();
    'TYP3' :
      StarteXMLPort3();
  END;
END;


Ich konnte dies jetzt auf die Schnelle nicht testen und es ist schon eine Zeit her, dass ich dies das letzte mal gemacht habe :oops: - sollte aber eigentlich so funktionieren.
Gruß
Frank

27. März 2007 13:12

Hallo,

erstmal danke für die schnellen Antworten.
@Michael: Den Text zu parsen wäre auch meine ultima ratio gewesen, aber da dies nicht so "schön" ist, wollte mein Auftraggeber das nicht so gerne.
Alle möglichen Tags anzugeben ist unmöglich, da im Laufe der Zeit immer mehr Formate dazu kommen werden und wir den General Info nicht jedesmal anpassen möchten.
@Frank: Wir haben ein bißchen Angst, dass wenn wir zwei verschiedene XML-Schnittstellen verwenden, es zu Problemen kommen kann, falls MS irgendwann einmal die Version nur eines der beiden ändert. Deswegen wollten wir nur entweder XML-Port oder XML-Automation. Der Ansatz gefällt mir (persönlich) aber auch ganz gut.
Ich habe es jetzt so gemacht:
ich habe die 3 Felder, die ich in dem XML-Port auslese, als globale Variablen einer Single-Instance-CodeUnit angelegt mit entsprechenden Set-Funktionen.
Beim Import werden diese Set-Funktionen dann aufgerufen und die Variablen gefüllt.
Den Abbruch Fehler habe ich mit einem "IF <XMLPort>.IMPORT THEN;" abgefangen.
So funktioniert es!

Gruß
Dirk

27. März 2007 20:12

Danke Dirk, da hast Du mich auch auf eine Idee gebracht, die ich für unsere Konvertierungstools nutzen kann!

16. Mai 2007 13:05

Gibt es ein Verzeichnis dieser XML-Befehle?
XMLNodeBody, XMLNode usw.