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