static void testReadMessage(Args _args)
{
VKMessage doc,
message,
activity,
id;
int a;
str xml = @'<Message>
<Activity>
<Id>ConfigurableProducts</Id>
</Activity>
<Activity>
<Id>ConfigurableProducts2</Id>
</Activity>
<TestNode>TestNodeValue</TestNode>
</Message>';
// construct message from source
doc = VKMessage::construct(xml);
// select Message node, return same VKMessage type
message = doc.selectNode('Message');
//message = doc.selectNode('Message/Activity'); // to access directly Activity node
// select Activity nodes in same way like 1 node selection
message.selectNode('Activity');
// get count of selected nodes and go though them
for (a = 0; a < message.getNodeCount(); a++)
{
// getNextNode starts from the first node
activity = message.getNextNode();
// select inbound Id node and get it's value
info(activity.selectNode('Id').getValue());
}
// sequential node selection
info(doc.selectNode('Message').selectNode('TestNode').getValue());
// use second parameter to select none existing nodes, getValue will return empty result in that case and you do not need to have additional check whether or not node was selected
info(doc.selectNode('DoesNotExist', true).getValue());
// This one will give runtime error
doc.selectNode('DoesNotExist').getValue();
}
Write XML message:static void testWriteMessage(Args _args)
{
VKMessage doc,
message,
activity,
id;
// construct new message of correct type
doc = VKMessage::construct();
// create new Message node. It will automatically append it to doc
message = doc.createNode('Message');
// create new ActivityNode which will be appended to Message node
activity= message.createNode('Activity');
// Create new Id node with value SomeId1 and append it to Activity node
activity.createNode('Id', 'SomeId1');
// Create additional Activity node on same Message level
activity= message.createNode('Activity');
activity.createNode('Id', 'SomeId2');
// get source of created document, XML
info(doc.getDocumentContent());
}
VKMessageXml doc,
sendClubProSettings,
clubProsList;
doc = VKMessage::construct(@'<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns0:sendClubProSettings xmlns:ns1="http://www.domain.com/docs/leisureClubPro" xmlns:ns0="http://leisureClubPro.ws.domain.com/">
</ns0:sendClubProSettings>
</S:Body>
</S:Envelope>');
doc.addNamespace('S', 'http://schemas.xmlsoap.org/soap/envelope/');
doc.addNamespace('ns0', 'http://leisureClubPro.ws.domain.com/');
sendClubProSettings = doc.selectNode('S:Envelope/S:Body/ns0:sendClubProSettings');
if (sendClubProSettings)
{
sendClubProSettings.createNode('TWSToken', 'token');
clubProsList = sendClubProSettings.createNode('ClubProsList');
clubProsList.createNode('Status', 'ADD');
clubProsList.createNode('Id', '123');
}
// get source of created document, XML
info(doc.getDocumentContent());
/// <summary>
/// Abstract class to handle messages of different formats
/// </summary>
abstract class VKMessage
{
/// <summary>
/// Create message node
/// </summary>
/// <param name = "_name">Name</param>
/// <param name = "_value">Value</param>
/// <param name = "_append">Append</param>
/// <returns>VKMessage</returns>
abstract public VKMessage createNode(str _name, str _value = '', boolean _append = true)
{
}
/// <summary>
/// Get document
/// </summary>
/// <returns>VKMessage</returns>
abstract public VKMessage getDocument()
{
}
/// <summary>
/// Get document content
/// </summary>
/// <returns>string</returns>
abstract public str getDocumentContent()
{
}
/// <summary>
/// Get next node
/// </summary>
/// <returns>VKMessageXml</returns>
abstract public VKMessage getNextNode()
{
}
/// <summary>
/// Get node count
/// </summary>
/// <returns>Int</returns>
abstract int getNodeCount()
{
}
/// <summary>
/// Get value
/// </summary>
/// <returns>str</returns>
abstract public str getValue()
{
}
/// <summary>
/// Init from string message
/// </summary>
/// <param name = "_message">String</param>
abstract public void initFromMessage(str _message)
{
}
/// <summary>
/// Select a node
/// </summary>
/// <param name = "_name">Name</param>
/// <param name = "_returnEmptyIfNone">Return empty if none</param>
/// <returns>VKMessage</returns>
abstract public VKMessage selectNode(str _name, boolean _returnEmptyIfNone = false)
{
}
/// <summary>
/// Constructor
/// </summary>
/// <param name = "_message">Message</param>
/// <param name = "_messageFormat">Message format</param>
/// <returns>VKMessage</returns>
static public VKMessage construct(str _message = '', VKMessageFormat _messageFormat = VKMessageFormat::Xml)
{
VKMessage message;
switch (_messageFormat)
{
case VKMessageFormat::Xml:
message = new VKMessageXml();
break;
default:
throw error(strFmt("%1: Unknown message format.", funcName()));
}
message.initFromMessage(_message);
return message;
}
}
/// <summary>
/// XML message implementation
/// </summary>
class VKMessageXml extends VKMessage
{
System.Xml.XmlDocument doc;
System.Xml.XmlElement selectedElement;
System.Xml.XmlNodeList nodeList;
int currentIndex;
System.Xml.XmlNamespaceManager nsmgr;
/// <summary>
/// Adds XML namespace
/// </summary>
/// <param name = "_nameSpace">name space</param>
/// <param name = "_nameSpaceUrl">name space URL</param>
public void addNamespace(str _nameSpace, str _nameSpaceUrl)
{
if (!nsmgr)
{
nsmgr = new System.Xml.XmlNamespaceManager(doc.NameTable);
}
nsmgr.AddNamespace(_nameSpace, _nameSpaceUrl);
}
public VKMessage createNode(str _name, str _value = '', boolean _append = true)
{
VKMessageXml message;
System.Xml.XmlElement createdElement;
createdElement = doc.CreateElement(_name);
if (_value)
{
createdElement.AppendChild(doc.CreateTextNode(_value));
}
if (_append)
{
if (selectedElement)
{
selectedElement.AppendChild(createdElement);
}
else
{
doc.AppendChild(createdElement);
}
}
message = new VKMessageXml();
message.initFromObject(doc, createdElement);
return message;
}
public VKMessage getDocument()
{
VKMessageXml message = new VKMessageXml();
message.initFromObject(doc, null);
return message;
}
public str getDocumentContent()
{
return doc.get_OuterXml();
}
public VKMessage getNextNode()
{
VKMessageXml message;
int elements;
if (nodeList)
{
elements = nodeList.get_Count();
}
if (elements && elements > currentIndex)
{
message = new VKMessageXml();
message.initFromObject(doc, nodeList.get_ItemOf(currentIndex));
currentIndex++;
}
return message;
}
public int getNodeCount()
{
int nodeCount = 0;
if (nodeList)
{
nodeCount = nodeList.get_Count();
}
return nodeCount;
}
public str getValue()
{
if (selectedElement)
{
return selectedElement.get_InnerText();
}
return '';
}
public void initFromMessage(str _message)
{
System.Xml.XmlException xmlError;
System.Exception ex;
System.String errorMsg;
str error;
doc = new System.Xml.XmlDocument();
doc.set_PreserveWhitespace(true);
if (_message)
{
try
{
doc.LoadXml(_message);
}
catch (Exception::CLRError)
{
ex = CLRInterop::getLastException();
if (null != ex)
{
xmlError = ex.get_InnerException();
if (null != xmlError)
{
errorMsg = xmlError.get_Message();
error = errorMsg;
}
}
throw error(strFmt("%1. XML Error: %2.", funcName(), error));
}
}
}
/// <summary>
/// Init from System.Xml.XmlDocument object
/// </summary>
/// <param name = "_doc">XmlDocument document</param>
/// <param name = "_selectedElement">selected element</param>
protected void initFromObject(System.Xml.XmlDocument _doc, System.Xml.XmlElement _selectedElement)
{
doc = _doc;
selectedElement = _selectedElement;
}
public VKMessage selectNode(str _name, boolean _returnEmptyIfNone = false)
{
VKMessageXml message;
int nCount;
currentIndex = 0;
if (selectedElement)
{
if (nsmgr)
{
nodeList = selectedElement.SelectNodes(_name, nsmgr);
}
else
{
nodeList = selectedElement.SelectNodes(_name);
}
}
else
{
if (nsmgr)
{
nodeList = doc.SelectNodes(_name, nsmgr);
}
else
{
nodeList = doc.SelectNodes(_name);
}
}
nCount = nodeList.get_Count();
if (nCount)
{
message = new VKMessageXml();
message.initFromObject(doc, nodeList.get_ItemOf(0));
}
else if (_returnEmptyIfNone)
{
message = new VKMessageXml();
message.initFromObject(doc, null);
}
return message;
}
}
If you found value in what I share, I've set up a Buy Me a Coffee page as a way to show your support.
Buy Me a CoffeeNo comments. Be the first one to comment on this post.
DaxOnline.org is free platform that allows you to quickly store and reuse snippets, notes, articles related to Dynamics 365 FO.
Authors are allowed to set their own "buy me a coffee" link.
Join us.