XML message wrapper

Want to work with XML as easy as in following examples, do not depend on XML format and have ability to change format to JSON?
Read XML message:
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');

    // 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());
}


Base abstract class to support several message formats:
abstract class VKMessage
{
}
abstract public VKMessage createNode(str _name, str _value = '', boolean _append = true)
{
}
abstract public VKMessage getDocument()
{
}
abstract public str getDocumentContent()
{
}
abstract public VKMessage getNextNode()
{
}
abstract int getNodeCount()
{
}
abstract public str getValue()
{
}
abstract public void initFromMessage(str _message)
{
}
abstract public VKMessage selectNode(str _name, boolean _returnEmptyIfNone = false)
{
}
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;
}
XML wrapper:
class VKMessageXml extends VKMessage
{
    System.Xml.XmlDocument  doc;
    System.Xml.XmlElement   selectedElement;
    System.Xml.XmlNodeList  nodeList;
    int                     currentIndex;
}
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));
        }
    }
}
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)
    {
        nodeList = selectedElement.SelectNodes(_name);
    }
    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;
}

Search

About

DaxOnline.org is free platform that allows you to quickly store and reuse snippets, notes, articles related to Dynamics AX.

Authors are allowed to set their own AdSense units.
Join us.

Blog Tags