Working with XML Files via MSXML 6.0

To work with MSXML 6.0, the Xml assembly has the DOMDocument60 and FreeThreadedDOMDocument60 classes. In Foresight Analytics Platform and starting with Prognoz Platform 8.0 working with all XML files is made via MSXML 6.0 (inheritance of the DOMDocument, DOMDocument40 and FreeThreadedDOMDocument classes is changed), that is why the current application code may not work properly. This is caused by change in working algorithm of system functions in the aspect of consideration of XML file namespaces. For example, there is the source file Data.xml with the following contents:

<?xml version="1.0" encoding="utf-8"?>

<root xmlns="http://www.w3.org/1999/xhtml">

  <items>

    <item>A</item>

    <item>B</item>

    <item>C</item>

  </items>

</root>

The following code was used to work with this file:

Sub LoadXML;
Var
    XMLDoc: IXMLDOMDocument;
    XMLName: String = "c:\Data.xml";
    Loaded: Boolean;
    Nodes: IXmlDomNodeList;
Begin
    XMLDoc := New DOMDocument.Create;
    Loaded := XMLDoc.load(XMLName);
    //...
    If Loaded Then
        //Get nodes
        Nodes := XMLDOc.documentElement.childNodes;
        Debug.WriteLine(Nodes.length);
        Nodes := XMLDOc.getElementsByTagName("root"); //Get the "root" element
        Debug.WriteLine(Nodes.length);
        Nodes := XMLDOc.getElementsByTagName("items"); //Get the "items" element
        Debug.WriteLine(Nodes.length);
        Nodes := XMLDOc.getElementsByTagName("item"); //Get all "item" elements
        Debug.WriteLine(Nodes.length);
    End If;
End Sub LoadXML;

On working via MSXML 3.0 this code would return 1, 1 and 3 nodes, respectively. After updating to Foresight Analytics Platform or Prognoz Platform 8.0 or later, MSXML 6.0 is used to execute this code, and the code returns the following values: 1, 0, 0. The getElementsByTagName method does not recognize default namespace that is why cannot find the specified elements. To solve the issue, remove the default namespace or set some prefix for it:

<?xml version="1.0" encoding="utf-8"?>

<root xmlns:ns="http://www.w3.org/1999/xhtml">

  <items>

    <item>A</item>

    <item>B</item>

    <item>C</item>

  </items>

</root>

The specified above method is relevant if it is available to edit the XML file in use. If there is not such possibility, it is available to use the program method of entering namespace with prefix. For details about this method see the MSDN: https://support.microsoft.com/ru-ru/kb/313372. In the Fore the required setProperty method that is used to set the SelectionNamespaces internal property is available in the IXMLDOMDocument2 interface. Application code is changed as follows:

Sub LoadXML;
Var
    XMLDoc: IXMLDOMDocument2;
    XMLName: String = "c:\Data.xml";
    Loaded: Boolean;
    Nodes: IXmlDomNodeList;
Begin
    XMLDoc := New DOMDocument.Create;
    XMLDoc.setProperty("SelectionNamespaces""xmlns:ns=""http://www.w3.org/1999/xhtml""");
    Loaded := XMLDoc.load(XMLName);
    //...
    If Loaded Then
        //Get child nodes of root node
        Nodes := XMLDOc.documentElement.childNodes;
        Debug.WriteLine(Nodes.length);
        Nodes := XMLDOc.selectNodes("ns:root"); //Get the "root" element
        Debug.WriteLine(Nodes.length);
        Nodes := XMLDOc.selectNodes("//ns:items"); //Get the "items" element
        Debug.WriteLine(Nodes.length);
        Nodes := XMLDOc.selectNodes("//ns:item"); //Get all "item" elements
        Debug.WriteLine(Nodes.length);
    End If;
End Sub LoadXML;

See also:

The XML Assembly | Examples of Working with XML Files