XML DOM Import

26. Oktober 2009 17:25

Hallo Forum,

ich habe aus Navision heraus, testweise, folgende XML-Datei erzeugt:
Code:
- <PURCHASEORDER>
  - <PURCHASEORDERHEADER>
    <DOCUMENTNO>110905994</DOCUMENTNO>
  </PURCHASEORDERHEADER>
  - <PURCHASEORDERLINE>
    <LINENO>10000</LINENO>
    <LINENO>20000</LINENO>
  </PURCHASEORDERLINE>
</PURCHASEORDER>

Also einen Kopf mit zwei Zeilen.

Jetzt will ich das Ganze einlesen. Dazu habe rufe ich in einer Codeunit eine Funktion mit folgendem Code auf:
Code:
Variablen:
Name                              DataType           Subtype
XMLDOMDocument           Automation   'Microsoft XML, v3.0'.DOMDocument   
XMLDOMManagement           Codeunit           XML DOM Management   
CurrNode                          Automation       'Microsoft XML, v3.0'.IXMLDOMNode   
XMLNodeFound                   Automation   'Microsoft XML, v3.0'.IXMLDOMNode   


IF ISCLEAR(XMLDOMDocument)  THEN
  CREATE(XMLDOMDocument);
XMLDOMDocument.load('c:\Test\Export\Test.xml' );
CurrNode := XMLDOMDocument.documentElement;
WITH XMLDOMManagement DO BEGIN
  IF FindNode(CurrNode, 'PURCHASEORDERHEADER', XMLNodeFound) THEN BEGIN
    CurrNode := XMLNodeFound;
    IF NOT FindNode(CurrNode,'DOCUMENTNO',XMLNodeFound) THEN
      EXIT
    ELSE
      IF STRLEN(XMLNodeFound.text) > 0 THEN BEGIN
        Message('%1',XMLNodeFound.text)
      END;
    CurrNode := CurrNode.parentNode;
  END;
  IF FindNode(CurrNode, 'PURCHASEORDERLINE', XMLNodeFound) THEN BEGIN
//-------------Repeat ?????????
    CurrNode := XMLNodeFound;
    IF NOT FindNode(CurrNode,'LINENO',XMLNodeFound) THEN
      EXIT
    ELSE
      IF STRLEN(XMLNodeFound.text) > 0 THEN BEGIN
         MESSAGE('%1',XMLNodeFound.text);
      END;
    CurrNode := CurrNode.parentNode;
//-------------Until ????????
  END;
END;
CLEAR(XMLDOMDocument);

Wenn ich das ausführe zeigt mir Navision zwei Messages an:
die 1. mit der Dokumentennr. 110905994
und die zweite mit der Zeilennr. 10000
Wie baue ich das "Repeat - Until" so ein, dass mir Navision in einer weiteren Message die Zeilennr. 20000 auch anzeigt? Also wie kann ich Navision dazu veranlassen im Tag "PURCHASEORDERLINE" das Tag "LINENO" eben mehrfach durchzugehen.
Da ich das ganze dynamisch benötige, scheidet ein XML-Port aus.

Ich hoffe jemand kann mir helfen, Danke.

Re: XML DOM Import

26. Oktober 2009 17:37

Hallo svr,

mit

Code:
xmlNodeList := DocNode.SelectNodelist('PURCHASEORDERLINE');
ItemCount := xmlNodeList.Length;
i:=0;
while (i < ItemCount) do begin
.......
end;



Gruß, Fiddi

Re: XML DOM Import

26. Oktober 2009 17:48

Kurze Frage noch:

was für Variablentypen sind
xmlNodeList bzw.
DocNode ?

Re: XML DOM Import

26. Oktober 2009 18:25

Hallo svr,

du solltest auf MSXML 4 oder höher ausweichen.

Code:
Name   DataType   Subtype   Length
XMLDoc   Automation   'Microsoft XML, v4.0'.DOMDocument   
XMLMainNodeList   Automation   'Microsoft XML, v4.0'.IXMLDOMNodeList   


Gruß, Fiddi

Re: XML DOM Import

27. Oktober 2009 10:08

Danke Fiddi, für Deine Hinweise.
Aber irgendwie klappt das nicht.
Vielleicht liegt es daran, dass mir die XML-Funktionen nicht so klar sind.
Ich kriege es einfach nicht gebacken, die LINENO durchzugehen und per Message auszugeben.
Hat jemand noch eine Idee (am besten auf mein Beispiel bezogen)?

Re: XML DOM Import

7. April 2010 11:29

Mir ist durchaus aufgefallen, dass dieser Thread schon vom vorigen Jahr ist.

Nun habe ich aktuell erstmals selber die Notwendigkeit, über den DOM Daten aus XML-Dateien und deren Nodes zu lesen.
Leider bin ich mit den hier gefundenen Beispielen nicht direkt klar gekommen. Es war mir konzeptionell nicht ganz klar,
und ich habe beispielsweise nach der Methode "SelectNodeList" gesucht, die aber "SelectNodes" heißt ... (?)

Nach ein bischen Fummelei habe ich die Grundzüge nun verstanden, und es erschien mir daher sinnvoll hier noch ein
vollständig lauffähiges Beispiel einzustellen.

Interessant fand ich als DOM Neuling:
Dass man direkt einen Pfad zu einem Node angeben kann -> '//PURCHASEORDERLINE/LINENO'
Dass die "items" der "Nodelist" 0-basiert sind
Dass die eigentlichen Daten über "text" und nicht über "value" lesbar sind

Code:
LocXMLDoc@1000000000 : Automation 'Microsoft XML, v4.0'.DOMDocument";
LocXMLNode@1000000004 : Automation 'Microsoft XML, v4.0'.IXMLDOMNode";
LocXMLNodeList@1000000001 : Automation 'Microsoft XML, v4.0'.IXMLDOMNodeList";
ItemCount@1000000003 : Integer;
i@1000000002 : Integer;

IF ISCLEAR(LocXMLDoc) THEN CREATE(LocXMLDoc);

IF LocXMLDoc.load('D:\test.xml') THEN BEGIN
  LocXMLNode := LocXMLDoc.documentElement();
  MESSAGE('Root is: %1', LocXMLNode.nodeName);

  LocXMLNodeList := LocXMLNode.selectNodes('//PURCHASEORDERLINE/LINENO');
  ItemCount := LocXMLNodeList.length;

  i:=0;
  WHILE (i < ItemCount) DO BEGIN
    MESSAGE( '%1', LocXMLNodeList.item(i).text );
    i += 1;
  END;
END ELSE BEGIN
  MESSAGE('Die XML-Datei konnte nicht geladen werden!');
END;


Dass die Beispieldaten für eine typische Bestellung nicht wirklich repräsentativ sind, bitte ich hier zu tolerieren ;-)

Code:
<?xml version="1.0" ?>
<PURCHASEORDER>
  <PURCHASEORDERHEADER>
  <DOCUMENTNO>110905994</DOCUMENTNO>
  </PURCHASEORDERHEADER>
    <PURCHASEORDERLINE>
      <LINENO>10000</LINENO>
      <LINENO>20000</LINENO>
      <LINENO>30000</LINENO>
      <LINENO>40000</LINENO>
    </PURCHASEORDERLINE>
    <PURCHASEORDERLINE>
      <LINENO>10000</LINENO>
      <LINENO>20000</LINENO>
      <LINENO>30000</LINENO>
    </PURCHASEORDERLINE>
</PURCHASEORDER>


Vielleicht nutzt es jemandem, leichter den Einstieg zu finden

Pidi