Для работы с MSXML версии 6.0 в сборке Xml предназначены классы DOMDocument60 и FreeThreadedDOMDocument60. В «Форсайт. Аналитическая платформа» и начиная с Prognoz Platform версии 8.0 работа со всеми XML файлами осуществляется через MSXML версии 6.0 (изменено наследование классов DOMDocument, DOMDocument40 и FreeThreadedDOMDocument), поэтому имеющийся код приложения может перестать работать. Это связано с изменением алгоритма работы системных функций в плане учета пространств имен XML-файла. Например, имеется исходный файл «Data.xml» со следующим содержимым:
<?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>
Для работы с данным файлом использовался следующий код:
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
//Получение вершин
Nodes := XMLDOc.documentElement.childNodes;
Debug.WriteLine(Nodes.length);
Nodes := XMLDOc.getElementsByTagName("root"); //Получить элемент root
Debug.WriteLine(Nodes.length);
Nodes := XMLDOc.getElementsByTagName("items"); //Получить элемент items
Debug.WriteLine(Nodes.length);
Nodes := XMLDOc.getElementsByTagName("item"); //Получить все элементы item
Debug.WriteLine(Nodes.length);
End If;
End Sub LoadXML;
При работе через MSXML 3.0 данный код вернул бы соответственно 1, 1 и 3 вершины. После перехода на продукт «Форсайт. Аналитическая платформа» или Prognoz Platform версии 8.0 и выше для выполнения данного кода будет использоваться MSXML 6.0 и код вернет следующие значения: 1, 0, 0. Метод getElementsByTagName не распознает пространство имен по умолчанию и поэтому не найдет указанные элементы. Для решения проблемы необходимо убрать пространство имен по умолчанию или задать для него какой-либо префикс:
<?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>
Указанный выше способ подходит если имеется возможность изменить используемый XML-файл. Если такой возможности нет, то можно воспользоваться программным способом введения пространства имен с префиксом. Более подробно данный способ описан в MSDN: https://support.microsoft.com/ru-ru/kb/313372. В Fore необходимый метод setProperty, который используется для задания внутреннего свойства SelectionNamespaces, доступен в интерфейсе IXMLDOMDocument2. Код приложения при этом изменится следующим способом:
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
//Получение вершин, дочерних для корневой вершины
Nodes := XMLDOc.documentElement.childNodes;
Debug.WriteLine(Nodes.length);
Nodes := XMLDOc.selectNodes("ns:root"); //Получить элемент root
Debug.WriteLine(Nodes.length);
Nodes := XMLDOc.selectNodes("//ns:items"); //Получить элемент items
Debug.WriteLine(Nodes.length);
Nodes := XMLDOc.selectNodes("//ns:item"); //Получить все элементы item
Debug.WriteLine(Nodes.length);
End If;
End Sub LoadXML;
См. также: