I called external web service and when a response was received, I saved the XML file. Now I want to import the data from that XML file into the table. But with the XML file structure I am unable to import
Please let me know how the XML structure will look like? What properties needed to set? Or will these type of files imported only through code?
Codeunit
OBJECT Codeunit 90001 Web Service Test
{
OBJECT-PROPERTIES
{
Date=05-03-19;
Time=19:07:12;
Modified=Yes;
Version List=;
}
PROPERTIES
{
OnRun=BEGIN
WebServiceFunctionA;
END;
}
CODE
{
LOCAL PROCEDURE WebServiceFunctionA@5();
VAR
uriObj@1000 : DotNet "'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Uri";
Request@1001 : DotNet "'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Net.HttpWebRequest";
Stream@1002 : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.IO.StreamWriter";
Response@1003 : DotNet "'System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Net.HttpWebResponse";
Reader@1004 : DotNet "'System.xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlTextReader";
document@1005 : DotNet "'System.xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Xml.XmlDocument";
ascii@1006 : DotNet "'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.System.Text.Encoding";
FileMgt@1007 : Codeunit 419;
FileSrv@1008 : Text;
ToFile@1009 : Text;
Xml@1010 : Text;
url@1011 : Text;
SoapAction@1012 : Text;
BEGIN
Xml := '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="
http://www.w3.org/2001/XMLSchema" xmlns:soap="
http://schemas.xmlsoap.org/soap/envelope/"><soap:Body>'+
'<GetHolidaysForYear xmlns="
http://www.holidaywebservice.com/HolidayService_v2/">'+
'<countryCode>UnitedStates</countryCode>'+
'<year>2019</year>'+
'</GetHolidaysForYear>'+
'</soap:Body></soap:Envelope>';
url := '
http://www.holidaywebservice.com/HolidayService_v2/HolidayService2.asmx';
uriObj := uriObj.Uri(url);
Request := Request.CreateDefault(uriObj);
Request.Method := 'POST';
Request.ContentType := 'text/xml';
SoapAction := '
http://www.holidaywebservice.com/HolidayService_v2/GetHolidaysForYear';
Request.Headers.Add('SOAPAction', SoapAction);
Request.Timeout := 120000;
// Send the request to the webservice
Stream := Stream.StreamWriter(Request.GetRequestStream(), ascii.UTF8);
Stream.Write(Xml);
Stream.Close();
// Get the response
Response := Request.GetResponse();
Reader := Reader.XmlTextReader(Response.GetResponseStream());
// Save the response to a XML
document := document.XmlDocument();
document.Load(Reader);
FileSrv := FileMgt.ServerTempFileName('xml');
document.Save(FileSrv);
// Get from the server
ToFile := FileMgt.ClientTempFileName('xml');
FileMgt.DownloadToFile(FileSrv, ToFile);
// Show the response XML
HYPERLINK(ToFile);
END;
BEGIN
END.
}
}
XMLFILE
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="
http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="
http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetHolidaysForYearResponse xmlns="
http://www.holidaywebservice.com/HolidayService_v2/">
<GetHolidaysForYearResult>
<Holiday>
<Country>UnitedStates</Country>
<HolidayCode>NEW-YEARS-DAY-ACTUAL</HolidayCode>
<Descriptor>New Year's Day</Descriptor>
<HolidayType>Other</HolidayType>
<DateType>Actual</DateType>
<BankHoliday>NotRecognized</BankHoliday>
<Date>2019-01-01T00:00:00</Date>
<RelatedHolidayCode>NEW-YEARS-DAY-OBSERVED</RelatedHolidayCode>
</Holiday>
</GetHolidaysForYearResult>
</GetHolidaysForYearResponse>
</soap:Body>
</soap:Envelope>
Thanks in advance for the help.
Answers
Afterwards, use this tool to generate nav xml:
https://mibuso.com/downloads/dynamics-nav-xmlport-generator-v1.3
Or just do it manually, this isn't a very complicated xml (soap) structure.
Remove all the stuff that is not needed before importing the xml file with the xmlport:
TempBlob.Blob.CREATEOUTSTREAM(OutStreamStylesheet);
TempBlob.Blob.CREATEINSTREAM(InStreamStylesheet);
OutStreamStylesheet.WRITETEXT('<?xml version="1.0" encoding="UTF-8"?>');
OutStreamStylesheet.WRITETEXT('<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">');
OutStreamStylesheet.WRITETEXT('<xsl:output method="xml" encoding="UTF-8" />');
OutStreamStylesheet.WRITETEXT('<xsl:template match="/">');
OutStreamStylesheet.WRITETEXT('<xsl:copy>');
OutStreamStylesheet.WRITETEXT('<xsl:apply-templates />');
OutStreamStylesheet.WRITETEXT('</xsl:copy>');
OutStreamStylesheet.WRITETEXT('</xsl:template>');
OutStreamStylesheet.WRITETEXT('<xsl:template match="*">');
OutStreamStylesheet.WRITETEXT('<xsl:element name="{local-name()}">');
OutStreamStylesheet.WRITETEXT('<xsl:apply-templates select="@* | node()" />');
OutStreamStylesheet.WRITETEXT('</xsl:element>');
OutStreamStylesheet.WRITETEXT('</xsl:template>');
OutStreamStylesheet.WRITETEXT('<xsl:template match="@*">');
OutStreamStylesheet.WRITETEXT('<xsl:attribute name="{local-name()}"><xsl:value-of select="."/></xsl:attribute>');
OutStreamStylesheet.WRITETEXT('</xsl:template>');
OutStreamStylesheet.WRITETEXT('<xsl:template match="text() | processing-instruction() | comment()">');
OutStreamStylesheet.WRITETEXT('<xsl:copy />');
OutStreamStylesheet.WRITETEXT('</xsl:template>');
OutStreamStylesheet.WRITETEXT('<xsl:template match="@*[local-name(.)=''noNamespaceSchemaLocation'']"/>');
OutStreamStylesheet.WRITETEXT('</xsl:stylesheet>');
IF ISCLEAR(XMLStyleSheet) THEN
CREATE(XMLStyleSheet);
XMLStyleSheet.load(InStreamStylesheet);
IF ISCLEAR(XMLDestinationDocument) THEN
CREATE(XMLDestinationDocument);
XMLSourceDocument.transformNodeToObject(XMLStyleSheet,XMLDestinationDocument);
OR
xmldom is just as easy
https://blogs.msdn.microsoft.com/nav/2010/03/24/how-to-createread-xml-file-from-microsoft-dynamics-nav-without-using-xmlports/
(use .net iso automation, look at, or just use CU 6224 XML DOM Management).
https://rockwithnav.wordpress.com/2016/03/29/remove-namespace-web-service-response-dotnet-variable/
Blog - rockwithnav.wordpress.com/
Twitter - https://twitter.com/RockwithNav
Facebook - https://facebook.com/rockwithnav/
No PM,please use the forum. || May the <SOLVED>-attribute be in your title!
i tried your suggestion to remove the namespaces but was unsuccessful.
Can you please edit the XML provided by Chirag and update in your code using style sheet?
And also if we copy the code to remove namespaces in separate function then how will this function
be called with parameters?
Your help will be appreciated.
Thanks!!!
If you're not acquainted with it, try to search for documentation.
All the other stuff that sometimes has to be done just to be able to use xmlports is way too much effort.
Though the newest nav versions have a lot of new fucntionality in xmlports
Below the code, it is not tested, and based on automation. But dotnet shouldn't be much different.
Path := '//soap:Envelope/soap:Body/GetHolidaysForYearResponse/GetHolidaysForYearResult/Holiday
XMLNodeList := XMLDoc.selectNodes(Path);
FOR i := 0 TO XMLNodeList.length-1 DO BEGIN
RelatedHolidayCodeVar := GetNodeValue(XMLDoc,STRSUBSTNO('%1/%2',Path,'RelatedHolidayCode'),i);
end;
GetNodeValue(XMLDoc : Automation "'Microsoft XML, v3.0'.DOMDocument";Path : Text[1024];NodeNo : Integer) : Text[1024]
XMLNodeList := XMLDoc.selectNodes(Path);
IF XMLNodeList.length <> 0 THEN BEGIN
XMLNode := XMLNodeList.item(NodeNo);
EXIT(XMLNode.text);
end;
END ELSE
ERROR('not found');
This is the function to remove Namespaces for NAV2013 and up:
The parameters are:
XMLDocIn and XMLDocOut could be the same var.
And the vars are:
ORIGINAL XML
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetHolidaysForYearResponse xmlns="http://www.holidaywebservice.com/HolidayService_v2/">
<GetHolidaysForYearResult>
<Holiday>
<Country>UnitedStates</Country>
<HolidayCode>NEW-YEARS-DAY-ACTUAL</HolidayCode>
<Descriptor>New Year's Day</Descriptor>
<HolidayType>Other</HolidayType>
<DateType>Actual</DateType>
<BankHoliday>NotRecognized</BankHoliday>
<Date>2019-01-01T00:00:00</Date>
<RelatedHolidayCode>TEST1</RelatedHolidayCode>
</Holiday>
</GetHolidaysForYearResult>
</GetHolidaysForYearResponse>
</soap:Body>
</soap:Envelope>
AFTER REMOVING NAMESPACES
<?xml version="1.0" encoding="utf-16"?>
<Envelope>
<Body>
<GetHolidaysForYearResponse>
<GetHolidaysForYearResult>
<Holiday>
<Country>UnitedStates</Country>
<HolidayCode>NEW-YEARS-DAY-ACTUAL</HolidayCode>
<Descriptor>New Year's Day</Descriptor>
<HolidayType>Other</HolidayType>
<DateType>Actual</DateType>
<BankHoliday>NotRecognized</BankHoliday>
<Date>2019-01-01T00:00:00</Date>
<RelatedHolidayCode>TEST1</RelatedHolidayCode>
</Holiday>
</GetHolidaysForYearResult>
</GetHolidaysForYearResponse>
</Body>
</Envelope>
Now i am trying the other way, i.e. Third Party tool will call the web service published in NAV by sending file in XML format which will be stored in NAV tables.
For that i have published the codeunit with function that will have parameter as Big Text
NAVWebService1.SetGlobals(Payload);
NAVWebService1.RUN;
Codeunit NAVWebService1
In this codeunit, Big Text is stored as Global variable using function SetGlobals and then running the codeunit using RUN
function definition
LOCAL ImportRequestFromWebService(PayloadXML : BigText)
CLEAR(XMLDocIn);
CLEAR(XmlInStream);
CLEAR(XmlOutStream);
XMLDocIn := XMLDocIn.XmlDocument;
TempBlob.INIT;
TempBlob.Blob.CREATEOUTSTREAM(XmlOutStream);
PayloadXML.WRITE(XmlOutStream);
TempBlob.INSERT;
TempBlob.CALCFIELDS(Blob);
TempBlob.Blob.CREATEINSTREAM(XmlInStream);
XMLDocIn.Load(XmlInStream);
XMLDocIn.Save('D:\TestFile.xml');
I am testing it using Wizdler.
In image Wizdler 1, the highlighted part is copied as an xml
In image Wizdler 2, the highlighted error.
Request you to help to solve this issue.
Thank You!!!
If you want to send the XML in the image Wizdler1.jpg, I think that you need to wrap the second Envelop with:
<![CDATA[]]>
Regards.
After the Webserver change port 443, I could not connect to the Webservice
Please give me a solution. Thanks a lot