How to create/read xml file from Microsoft Dynamics NAV without using xmlports

Periodically we receive support requests about XMLport errors, which really are missing features in xmlport’s functionality.
However most of these requests are rejected because: xmlports are not supposed to fulfill all possible xml standard scenarios.
So there always will be xml file which can’t be created or readed by NAV xmlport.
Possible workaround could be to use XML DOM automations.

Create it by codeunit:

—————————————-

 OBJECT Codeunit 50052 xml create
{
  OBJECT-PROPERTIES
  {
    Date=03/24/10;
    Time=[ 1:33:31 PM];
    Modified=Yes;
    Version List=;
  }
  PROPERTIES
  {
    OnRun=BEGIN
            CREATE(xmlDoc);
            xmlMgt.SetNormalCase;
            xmlProcessingInst:=xmlDoc.createProcessingInstruction(‘xml’,’version=”1.0″ encoding=”UTF-8″ standalone=”yes”‘);

            CurrNode := xmlDoc.appendChild(xmlProcessingInst);
            CurrNode := xmlDoc.createElement(‘soapenv:Envelope’);
            CurrNode := xmlDoc.appendChild(CurrNode);

            xmlMgt.AddAttribute(CurrNode,’xmlns:soapenv’,’http://schemas.xmlsoap.org/soap/envelope/’);
            xmlMgt.AddAttribute(CurrNode,’xmlns:mbs’,’http://www.microsoft.com/mbs/xml’);

            xmlMgt.AddElement(CurrNode,’soapenv:Header’,”,’soapenv’,NewChild);
              CurrNode:=NewChild; //One level deeper
              xmlMgt.AddElement(CurrNode,’soapenv:Body’,”,’soapenv’,NewChild);
                   CurrNode:=NewChild; //one level deeper
                   xmlMgt.AddElement(CurrNode,’mbs:enumeration’,”,’mbs’,NewChild);
                        CurrNode:=NewChild; //one level deeper
                        xmlMgt.AddElement(CurrNode,’mbs:table’,’Customers’,’mbs’,NewChild);

                     recCustomer.SETRANGE(“No.”, ‘10000’,’20000′); //Filter only few records
                     IF recCustomer.FINDFIRST THEN BEGIN
                       REPEAT
                        vName   :=recCustomer.Name;
                        vNo     :=recCustomer.”No.”;
                        vContact:=recCustomer.Contact;
                          recCustomer.CALCFIELDS(“Balance (LCY)”);
                          vBalance:= FORMAT(recCustomer.”Balance (LCY)”);
                        vSPcode :=recCustomer.”Salesperson Code”;

                        xmlMgt.AddElement(CurrNode,’mbs:Customer’,”,’mbs’,NewChild);
                              CurrNode1:=NewChild; //One level deeper, but keep current level too
                              xmlMgt.AddElement(CurrNode1,’mbs:CustomerAuthentication’,”,’mbs’,NewChild);
                                     CurrNode2:=NewChild; //One level deeper to sublevel
                                     xmlMgt.AddElement(CurrNode2,’mbs:No’,vNo,’mbs’,NewChild);
                                     xmlMgt.AddElement(CurrNode2,’mbs:Name’,vName,’mbs’,NewChild);

                              xmlMgt.AddElement(CurrNode1,’mbs:CustomerData’,”,’mbs’,NewChild);
                                     CurrNode2:=NewChild; //One level deeper to sublevel
                                     xmlMgt.AddElement(CurrNode2,’mbs:Balance’,vBalance,’mbs’,NewChild);
                                     xmlMgt.AddElement(CurrNode2,’mbs:SalespersonCode’,vSPcode,’mbs’,NewChild);
                                     xmlMgt.AddElement(CurrNode2,’mbs:Contacts’,”,’mbs’,NewChild);
                                         CurrNode1:=NewChild;//One level deeper
                                         xmlMgt.AddElement(CurrNode1,’mbs:Contact’,vContact,’mbs’,NewChild);

                        CLEAR(vName);
                        CLEAR(vNo)  ;
                        CLEAR(vContact);
                        CLEAR(vBalance);
                        CLEAR(vSPcode);

                       UNTIL recCustomer.NEXT=0;

                       xmlDoc.save(‘D:\xmlFile.xml’);
                       CLEARALL;
                       MESSAGE(‘xmlFile.xml is created’);
                     END;
          END;

  }
  CODE
  {
    VAR
      xmlDoc@1000 : Automation “{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:’Microsoft XML, v6.0′.DOMDocument”;
      CurrNode@1003 : Automation “{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:’Microsoft XML, v6.0′.IXMLDOMNode”;
      CurrNode1@1005 : Automation “{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:’Microsoft XML, v6.0′.IXMLDOMNode”;
      CurrNode2@1013 : Automation “{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:’Microsoft XML, v6.0′.IXMLDOMNode”;
      NewChild@1004 : Automation “{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:’Microsoft XML, v6.0′.IXMLDOMNode”;
      xmlProcessingInst@1001 : Automation “{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF89-7B36-11D2-B20E-00C04F983E60}:’Microsoft XML, v6.0′.IXMLDOMProcessingInstruction”;
      xmlMgt@1002 : Codeunit 6224;
      “—- Variables—-“@1006 : Integer;
      recCustomer@1012 : Record 18;
      vName@1007 : Text[30];
      vNo@1008 : Text[30];
      vContact@1009 : Text[30];
      vBalance@1010 : Text[30];
      vSPcode@1011 : Text[30];

    EVENT xmlDoc@1000::ondataavailable@198();
    BEGIN
    END;

    EVENT xmlDoc@1000::onreadystatechange@-609();
    BEGIN
    END;

    BEGIN
    END.
  }
}

—————————————

And can be read by codeunit: 

OBJECT Codeunit 50050 xml read
{
  OBJECT-PROPERTIES
  {
    Date=03/24/10;
    Time=12:25:26 PM;
    Modified=Yes;
    Version List=;
  }
  PROPERTIES
  {
    OnRun=BEGIN
            ffile.OPEN(‘D:\XmlFile.xml’); //this must be your file name
            ffile.CREATEINSTREAM(strInStream);

            IF ISCLEAR(xmldomDoc) THEN CREATE(xmldomDoc);

            xmldomDoc.load(strInStream);

            xmlNodeList1 := xmldomDoc.getElementsByTagName(‘mbs:Customer’);

            ii:=xmlNodeList1.length();

            FOR i:=0 TO xmlNodeList1.length()-1 DO BEGIN
             xmldomElem1:= xmlNodeList1.item(i); //mbs:Customer
             IF xmldomElem1.hasChildNodes() THEN
                BEGIN
                  xmlNodeList2:= xmldomElem1.childNodes();
                  IF NOT ISCLEAR(xmlNodeList2) THEN
                  xmldomElem2:= xmlNodeList2.item(0); //mbs:CustomerAuthentication
                  IF NOT ISCLEAR(xmldomElem2) THEN
                  IF xmldomElem2.hasChildNodes() THEN
                     BEGIN
                     xmlNodeList3:= xmldomElem2.childNodes();
                     IF NOT ISCLEAR(xmlNodeList3) THEN
                      xmldomElem3:= xmldomElem2.firstChild();//mbs:No
                     IF NOT ISCLEAR(xmldomElem3) THEN
                      txtNo:=xmldomElem3.text();
                     xmldomElem3:=xmlNodeList3.item(1); //mbsName
                     IF NOT ISCLEAR(xmldomElem3) THEN
                      txtName:=xmldomElem3.text();

                  xmldomElem2:= xmlNodeList2.item(1); //mbs:CustomerData
                  IF NOT ISCLEAR(xmldomElem2) THEN
                  IF xmldomElem2.hasChildNodes() THEN
                     BEGIN
                     xmlNodeList3:= xmldomElem2.childNodes();
                     IF NOT ISCLEAR(xmlNodeList3) THEN
                      xmldomElem3:= xmldomElem2.firstChild();//mbs:Balance
                     IF NOT ISCLEAR(xmldomElem3) THEN
                      txtBalance:=xmldomElem3.text();
                     xmldomElem3:=xmlNodeList3.item(1); //mbsSalesPersonCode
                     IF NOT ISCLEAR(xmldomElem3) THEN
                      txtSPcode:=xmldomElem3.text();
                     END;

                     xmldomElem3:=xmlNodeList3.item(2); //mbs:Contacts
                     IF NOT ISCLEAR(xmldomElem3) THEN
                        txtContact:=xmldomElem3.text();

                 END;
            END;
                  MESSAGE(‘This is record “%1″\No “%2″\Name “%3″\Contact “%4″\Balance “%5″\Salesperson code “%6″\of Total “%7″‘,
                  FORMAT(i+1),
                  txtNo,
                  txtName,
                  txtContact,
                  txtBalance,
                  txtSPcode,
                  ii);

            END;
            ffile.CLOSE;
            CLEARALL;
          END;

  }
  CODE
  {
    VAR
      xmldomDoc@1000 : Automation “{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:’Microsoft XML, v6.0′.DOMDocument”;
      xmlNodeList1@1005 : Automation “{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF82-7B36-11D2-B20E-00C04F983E60}:’Microsoft XML, v6.0′.IXMLDOMNodeList”;
      xmlNodeList2@1017 : Automation “{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF82-7B36-11D2-B20E-00C04F983E60}:’Microsoft XML, v6.0′.IXMLDOMNodeList”;
      xmlNodeList3@1019 : Automation “{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF82-7B36-11D2-B20E-00C04F983E60}:’Microsoft XML, v6.0′.IXMLDOMNodeList”;
      xmldomElem1@1007 : Automation “{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF86-7B36-11D2-B20E-00C04F983E60}:’Microsoft XML, v6.0′.IXMLDOMElement”;
      xmldomElem2@1010 : Automation “{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF86-7B36-11D2-B20E-00C04F983E60}:’Microsoft XML, v6.0′.IXMLDOMElement”;
      xmldomElem3@1011 : Automation “{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF86-7B36-11D2-B20E-00C04F983E60}:’Microsoft XML, v6.0′.IXMLDOMElement”;
      txtNo@1001 : Text[30];
      txtName@1002 : Text[30];
      txtContact@1009 : Text[30];
      txtBalance@1012 : Text[30];
      txtSPcode@1013 : Text[30];
      ffile@1003 : File;
      strInStream@1004 : InStream;
      i@1006 : Integer;
      ii@1018 : Integer;

    EVENT xmldomDoc@1000::ondataavailable@198();
    BEGIN
    END;

    EVENT xmldomDoc@1000::onreadystatechange@-609();
    BEGIN
    END;

    BEGIN
    END.
  }
}

That’s all
Special thanks to
Rainer Kuhnlein

Gedas Busniauskas (gediminb)
Microsoft Customer Service and Support (CSS) EMEA

 

xmlFile.xml