XMLnode := XmlDoc.selectSingleNode('element/node');
DocFragment := XmlRequest.createDocumentFragment();
DocFragment.appendChild(NewDocument.documentElement);
XMLnode.appendChild(DocFragment);
Navision Code
My own memory stak for Navision code examples. My virtual post-it notes.
mandag den 2. april 2012
mandag den 12. marts 2012
Tracking Usage with Google Analytics
utm_url := utm_location + '?' +
'utmwv=' + Version +
'&utmn=' + random_number +
'&utmhn=' + 'loggersite.com' +
'&utmr=' + 'user' +
'&utmp=' + UrlEncode('/', '%2F') +
'&utmac=' + 'macid' +
'&utmcc=__utma%3D999.999.999.999.999.1%3B' +
'&utmvid=' + 'VisitorId';
'utmwv=' + Version +
'&utmn=' + random_number +
'&utmhn=' + 'loggersite.com' +
'&utmr=' + 'user' +
'&utmp=' + UrlEncode('/', '%2F') +
'&utmac=' + 'macid' +
'&utmcc=__utma%3D999.999.999.999.999.1%3B' +
'&utmvid=' + 'VisitorId';
onsdag den 11. januar 2012
Connecting to REST WebService from Navision
I will let the code speak for itself:
Complete CodeUnit:
.NET REST webservice implemented as a generic handler (.ashx) nothing fancy:
Complete CodeUnit:
OBJECT Codeunit 90002 WebService Connection
{
OBJECT-PROPERTIES
{
Date=11-01-12;
Time=15:05:21;
Modified=Yes;
Version List=;
}
PROPERTIES
{
OnRun=BEGIN
CREATE(XmlIn);
CREATE(XmlOut);
// Populating XmlIn document for test purposes
LoadTestXml();
// Invoke method
Send();
// Save result to disc
XmlOut.save('C:\Temp\XML\response.xml');
END;
}
CODE
{
VAR
XmlIn@1000000004 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v6.0'.DOMDocument";
XmlOut@1000000003 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v6.0'.DOMDocument";
locautXmlHttp@1160870000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{88D96A0A-F192-11D4-A65F-0040963251E5}:'Microsoft XML, v6.0'.XMLHTTP60";
PROCEDURE Send@1000000004();
BEGIN
// Communication
CREATE(locautXmlHttp);
locautXmlHttp.open('POST','http://localhost:56063/RESTservice.ashx',0);
locautXmlHttp.setRequestHeader('Content-type','text/xml; charset=utf-8');
locautXmlHttp.setRequestHeader('KeepAlive','false');
locautXmlHttp.setRequestHeader('Timeout','5000');
// Send request
locautXmlHttp.send(XmlIn);
// Get response
XmlOut := locautXmlHttp.responseXML;
XmlOut.async := TRUE;
// Show result
MESSAGE(XmlOut.xml);
END;
PROCEDURE LoadTestXml@1160870000();
BEGIN
XmlIn.loadXML(
'<xmltest>' +
'<test>' +
'This document can contain anything. But must not contain xml decleration.' +
'</test>' +
'</xmltest>');
END;
BEGIN
{
Shows how to connect to a REST Web Service
}
END.
}
}
.NET REST webservice implemented as a generic handler (.ashx) nothing fancy:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
namespace WebServiceApplication
{
/// <summary>
/// Summary description for RESTservice
/// </summary>
public class RESTservice : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string requestMethod = context.Request.HttpMethod; // POST, PUT, GET or DELETE
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.Load(context.Request.InputStream);
System.IO.Stream stream = context.Request.InputStream;
byte[] bytes = new byte[stream.Length];
stream.Position = 0; // Resetting reading position
stream.Read(bytes, 0, (int)stream.Length);
string data = Encoding.ASCII.GetString(bytes); // this is your string
//context.Response.ContentType = "text/plain";
context.Response.ContentType = "text/xml";
context.Response.Write("<result>Hello World</result>");
context.Response.End();
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
mandag den 9. januar 2012
Validating xml with a schema
A XML Schema is a contract on how the XML structure should look. In a data transmission both parts know how the XML document should/could look.
XML Schemas can only be used with XMLDocument60 previous versions only support DTD.
Implicit validation:
Explicit validation:
Complete CodeUnit examble:
XML Schemas can only be used with XMLDocument60 previous versions only support DTD.
Implicit validation:
doc.validateOnParse := true;
Explicit validation:
doc.validate();
Complete CodeUnit examble:
OBJECT Codeunit 90003 SchemaValidation
{
OBJECT-PROPERTIES
{
Date=09-01-12;
Time=15:22:39;
Modified=Yes;
Version List=;
}
PROPERTIES
{
OnRun=BEGIN
ImplicitValidate();
ExplicitValidate();
END;
}
CODE
{
VAR
XmlDocument@1160870000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{88D96A05-F192-11D4-A65F-0040963251E5}:'Microsoft XML, v6.0'.DOMDocument60";
XmlSchema@1160870001 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{88D96A05-F192-11D4-A65F-0040963251E5}:'Microsoft XML, v6.0'.DOMDocument60";
PROCEDURE ImplicitValidate@1160870001();
VAR
XmlSchemaCache@1160870000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{88D96A07-F192-11D4-A65F-0040963251E5}:'Microsoft XML, v6.0'.XMLSchemaCache60";
BEGIN
CLEAR(XmlDocument);
CLEAR(XmlSchemaCache);
CREATE(XmlSchemaCache);
CREATE(XmlDocument);
XmlDocument.async := FALSE;
// Populating Schema
LoadSchema();
// Apply schema to schemacache with namespace. '' apply to default namespace
XmlSchemaCache.add('', XmlSchema);
// apply schema to xmldocument
XmlDocument.schemas := XmlSchemaCache;
// validate data when loading of XML is finished
XmlDocument.validateOnParse := TRUE;
// loading xml into document. XML is parsed when loading is done and false is returned if schema validation failed
IF LoadXmlDocument() THEN BEGIN
MESSAGE('VALID IMPLICIT');
END
ELSE BEGIN
MESSAGE('ERROR IMPLICIT');
END;
// loading xml into document. XML is parsed when loading is done and false is returned if schema validation failed
IF LoadXmlDocumentWithError() THEN BEGIN
MESSAGE('VALID IMPLICIT');
END
ELSE BEGIN
MESSAGE('ERROR IMPLICIT');
END;
END;
PROCEDURE ExplicitValidate@1160870005();
VAR
XmlSchemaCache@1160870000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{88D96A07-F192-11D4-A65F-0040963251E5}:'Microsoft XML, v6.0'.XMLSchemaCache60";
XmlParseError@1160870001 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{3EFAA428-272F-11D2-836F-0000F87A7782}:'Microsoft XML, v6.0'.IXMLDOMParseError2";
BEGIN
CLEAR(XmlDocument);
CLEAR(XmlSchemaCache);
CREATE(XmlSchemaCache);
CREATE(XmlDocument);
XmlDocument.async := FALSE;
// Populating Schema
LoadSchema();
// Apply schema to schemacache with namespace. '' apply to default namespace
XmlSchemaCache.add('', XmlSchema);
// apply schema to xmldocument
XmlDocument.schemas := XmlSchemaCache;
// validate data when loading of XML is finished
XmlDocument.validateOnParse := FALSE;
// loading xml into document. XML is not parsed when loading is done and true is returned unless the XML convension is not complied
LoadXmlDocument();
// XML content is validated against the schema and a validation result object is returned.
XmlParseError := XmlDocument.validate();
// If errorCode is 0 then there was no errors in the validation
IF XmlParseError.errorCode = 0 THEN
BEGIN
MESSAGE('VALID EXPLICIT');
END
ELSE BEGIN
MESSAGE('ERROR EXPLICIT: ' + XmlParseError.reason + ' - ' + XmlParseError.srcText + ' - ' + FORMAT(XmlParseError.line));
END;
// loading xml into document. XML is not parsed when loading is done and true is returned unless the XML convension is not complied
LoadXmlDocumentWithError();
// XML content is validated against the schema and a validation result object is returned.
XmlParseError := XmlDocument.validate();
// If errorCode is 0 then there was no errors in the validation
IF XmlParseError.errorCode = 0 THEN
BEGIN
MESSAGE('VALID EXPLICIT');
END
ELSE BEGIN
MESSAGE('ERROR EXPLICIT: ' + XmlParseError.reason + ' - ' + XmlParseError.srcText + ' - ' + FORMAT(XmlParseError.line));
END;
END;
PROCEDURE LoadSchema@1160870002();
BEGIN
CLEAR(XmlSchema);
CREATE(XmlSchema);
XmlSchema.async := FALSE;
XmlSchema.loadXML(
'<?xml version="1.0" encoding="utf-8" ?>' +
'<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">' +
'<xs:element name="xmltest">' +
'<xs:complexType>' +
'<xs:sequence>' +
'<xs:element name="elem1">' +
'<xs:complexType>' +
'<xs:sequence>' +
'<xs:element name="elem2" type="xs:string" minOccurs="1" />' +
'<xs:element name="elem3" type="xs:unsignedByte" />' +
'<xs:element name="elem4" type="xs:decimal" />' +
'</xs:sequence>' +
'</xs:complexType>' +
'</xs:element>' +
'</xs:sequence>' +
'</xs:complexType>' +
'</xs:element>' +
'</xs:schema>');
END;
PROCEDURE LoadXmlDocument@1160870003() LoadSuccess : Boolean;
BEGIN
LoadSuccess := XmlDocument.loadXML(
'<?xml version="1.0" encoding="utf-8" ?>' +
'<xmltest>' +
'<elem1>' +
'<elem2>v‘rdi</elem2>' +
'<elem3>3</elem3>' +
'<elem4>1.5</elem4>' +
'</elem1>' +
'</xmltest>');
END;
PROCEDURE LoadXmlDocumentWithError@1160870004() LoadSuccess : Boolean;
BEGIN
LoadSuccess := XmlDocument.loadXML(
'<?xml version="1.0" encoding="utf-8" ?>' +
'<xmltest>' +
'<elem1>' +
// '<elem2>v‘rdi</elem2>' + // This makes an error <xs:element name="elem2" type="xs:string" minOccurs="1" />
'<elem3>3</elem3>' +
'<elem4>1.5</elem4>' +
'</elem1>' +
'</xmltest>');
END;
BEGIN
{
Shows how to validate XML using a XML-Schema
}
END.
}
}
mandag den 2. januar 2012
Getting XML Dom parse error in Navision
// Getting the Exception Message
ERROR(locautXmlDoc.parseError.reason);
// Getting the Code producing the error
ERROR(locautXmlDoc.parseError.srcText);
Connecting to SOAP WebService from Navision
Connect to a Soap Web Service using the XMLHttp contained in the Microsoft XML Automation.
Version 2. View version list at the bottom.
Complete CodeUnit;
Code examble of the .Net webservice:
Version List:
1. Init
2. Bufferoverflow error fixed:
XmlReply.loadXML(ResultNode.transformNode(DecodeXSLT)); was changed to
ResultNode.transformNodeToObject(DecodeXSLT, XmlReply); due to the loadXML uses the Navision
string buffer as temporary container for the decoded XML this means 1024 chars.
Version 2. View version list at the bottom.
// Communication
CREATE(locautXmlHttp);
locautXmlHttp.open('POST','http://localhost:56063/SoapService.asmx',0);
locautXmlHttp.setRequestHeader('Content-type','application/soap+xml; charset=utf-8');
locautXmlHttp.setRequestHeader('SOAPAction','http://tempuri.org/NavisionRequest');
locautXmlHttp.send(locautXmlDoc);
locautXmlDoc := locautXmlHttp.responseXML;
locautXmlDoc.async := TRUE;
Complete CodeUnit;
OBJECT Codeunit 90002 WebService Connection
{
OBJECT-PROPERTIES
{
Date=02-01-12;
Time=20:21:46;
Modified=Yes;
Version List=;
}
PROPERTIES
{
OnRun=BEGIN
CREATE(XmlIn);
CREATE(XmlOut);
// Populating XmlIn document for test purposes
LoadTestXml();
// Invoke method
Send(XmlIn, XmlOut, 'User', 'Pass');
// Save result to disc
XmlOut.save('C:\Temp\XML\response.xml');
END;
}
CODE
{
VAR
XmlIn@1000000004 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v6.0'.DOMDocument";
XmlOut@1000000003 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v6.0'.DOMDocument";
DecodeXSLT@1000000008 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v6.0'.DOMDocument";
locautXmlDoc@1000000010 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v6.0'.DOMDocument";
ResultNode@1000000011 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v6.0'.IXMLDOMNode";
PROCEDURE Send@1000000004(XmlRequest@1000000002 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v6.0'.DOMDocument";VAR XmlReply@1000000003 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{F6D90F11-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v6.0'.DOMDocument";User@1000000005 : Text[30];Password@1000000006 : Text[30]);
VAR
locautXmlHttp@1000000000 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{F6D90F16-9C73-11D3-B32E-00C04F990BB4}:'Microsoft XML, v6.0'.XMLHTTP";
bodyXMLnode@1000000004 : Automation "{F5078F18-C551-11D3-89B9-0000F81FE221} 6.0:{2933BF80-7B36-11D2-B20E-00C04F983E60}:'Microsoft XML, v6.0'.IXMLDOMNode";
BEGIN
CLEAR(XmlReply);
CREATE(XmlReply);
// Load Soap Envelope
LoadSendEnvelope(User,Password);;
// Load Transformation schema for URL-decode
LoadDecodeXlsSchema;
bodyXMLnode := locautXmlDoc.selectSingleNode('soap:Envelope/soap:Body/NavisionRequest/request');
// Inserting xml into text property it gets URL-encodes automatic
bodyXMLnode.text := XmlRequest.xml;
// Communication
CREATE(locautXmlHttp);
locautXmlHttp.open('POST','http://localhost:56063/SoapService.asmx',0);
locautXmlHttp.setRequestHeader('Content-type','application/soap+xml; charset=utf-8');
locautXmlHttp.setRequestHeader('SOAPAction','http://tempuri.org/NavisionRequest');
locautXmlHttp.send(locautXmlDoc);
locautXmlDoc := locautXmlHttp.responseXML;
locautXmlDoc.async := TRUE;
// Readin reply
XmlReply := locautXmlDoc;
// Fetching response
ResultNode := locautXmlDoc.selectSingleNode('soap:Envelope/soap:Body/NavisionRequestResponse/NavisionRequestResult');
// Parsing response
ResultNode.transformNodeToObject(DecodeXSLT, XmlReply);
END;
PROCEDURE LoadDecodeXlsSchema@1000000002();
BEGIN
CREATE(DecodeXSLT);
DecodeXSLT.loadXML(
'<?xml version="1.0" encoding="UTF-8" ?>' +
'<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">' +
'<xsl:output indent="yes" />' +
'<xsl:template match="*"> ' +
//'<xsl:element name="{local-name()}">' +
'<xsl:value-of select="." disable-output-escaping="yes"></xsl:value-of>' +
//'</xsl:element>' +
'</xsl:template>' +
'</xsl:stylesheet>');
END;
PROCEDURE LoadSendEnvelope@1000000006(parUser@1000000001 : Text[30];parPassword@1000000000 : Text[30]);
BEGIN
CREATE(locautXmlDoc);
locautXmlDoc.async := FALSE;
locautXmlDoc.loadXML(
'<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' +
'<soap:Body>' +
'<NavisionRequest xmlns="http://tempuri.org/">' +
'<username>'+parUser+'</username>' +
'<password>'+parPassword+'</password>' +
'<request><xmltest><value>test</value></xmltest></request>' +
'</NavisionRequest>' +
'</soap:Body>' +
'</soap:Envelope>');
END;
PROCEDURE LoadTestXml@1160870000();
BEGIN
XmlIn.loadXML(
'<xmltest>' +
'<test>' +
'This document can contain anything. But must not contain xml decleration.' +
'</test>' +
'</xmltest>');
END;
BEGIN
{
Shows how to connect to a SOAP Web Service.
Version 2. For change history view:
http://navcode.blogspot.com/2012/01/connecting-to-soap-webservice-from.html
}
END.
}
}
Code examble of the .Net webservice:
using System;
using System.Web;
using System.Web.Services;
namespace WebServiceApplication
{
/// <summary>
/// Web Service for Navision Integration purpose
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
public class SoapService : System.Web.Services.WebService
{
[WebMethod]
public string HelloNavision()
{
return "Hello Navision";
}
[WebMethod]
public string NavisionRequest(string username, string password, string request)
{
if (string.IsNullOrEmpty(request))
{
return "Tinfoilhat!";
}
System.Xml.XmlDocument resp = new System.Xml.XmlDocument();
resp.LoadXml(request);
return resp.OuterXml;
}
[WebMethod]
public void ParamTest(System.Xml.XmlDocument xmldoc)
{
}
}
}
Version List:
1. Init
2. Bufferoverflow error fixed:
XmlReply.loadXML(ResultNode.transformNode(DecodeXSLT)); was changed to
ResultNode.transformNodeToObject(DecodeXSLT, XmlReply); due to the loadXML uses the Navision
string buffer as temporary container for the decoded XML this means 1024 chars.
fredag den 16. december 2011
HTML Encode using the XMl DOM Automation
NAV Code:
CREATE(XMLDoc);
XMLDoc.load(XmlToBeEncoded);
IXMLDOMText := XMLDoc.createTextNode(XMLDoc.xml);
EncodedXml := IXMLDOMText
Abonner på:
Opslag (Atom)