Как указать пространство имен (Namespace) при выборе тегов XML в 1С

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При обработке XML-файлов с помощью COM-объекта MSXML2.DOMDocument часто возникает ситуация, когда методы selectNodes или selectSingleNode возвращают пустой результат. Причина заключается в наличии пространства имен по умолчанию (атрибут xmlns="http://hl7.org/fhir") в корневом узле документа.

Согласно спецификации XPath 1.0, если имя тега в запросе указывается без префикса (например, //MedicationPrescription), поиск выполняется только среди элементов без пространства имен. Если у документа задан дефолтный xmlns, все его дочерние узлы наследуют это пространство имен, и обычный XPath-запрос перестает их находить.

Рассмотрим несколько способов решения этой задачи при разработке на 1С.

Способ 1. Установка свойства SelectionNamespaces в MSXML (Рекомендуемый)

Для корректной работы XPath-запросов в MSXML2.DOMDocument необходимо зарегистрировать псевдоним (префикс) пространства имен с помощью метода setProperty. Заданный префикс (например, ns) затем используется во всех XPath-выражениях.

Разберем по шагам реализацию этого метода:

  1. Создаем объект MSXML2.DOMDocument.6.0 и загружаем XML-файл.
  2. Настраиваем свойство SelectionNamespaces, связывая нужный URI с префиксом.
  3. Выполняем выборку узлов с указанием префикса перед каждым тегом.

Посмотрим на пример кода:


XML = CreateObject("MSXML2.DOMDocument.6.0");
XML.Load("d:\файл.xml");

// Регистрируем пространство имен и задаем префикс ns
XML.setProperty("SelectionNamespaces", "xmlns:ns=""http://hl7.org/fhir""");

// Выполняем выборку узлов с использованием зарегистрированного префикса
all = XML.selectNodes("//ns:MedicationPrescription");
length = all.length;

Для i = 0 по length - 1 Цикл
    Узел = all.item(i);
    // Для обращения к дочерним элементам также обязательно указываем префикс
    УзелId = Узел.selectSingleNode("ns:id");
    Если ПустоеЗначение(УзелId) = 0 Тогда
        Значение = УзелId.getAttribute("value");
        Сообщить("Значение ID: " + Значение);
    КонецЕсли;
КонецЦикла;

Способ 2. Использование метода getElementsByTagName

Если для работы с документом не требуются сложные XPath-выражения, можно применить стандартный метод getElementsByTagName. Данный метод ищет узлы по их локальному имени, игнорируя пространства имен.

Проанализируем пример использования:


XML = CreateObject("MSXML2.DOMDocument.6.0");
XML.Load("d:\файл.xml");

// Получаем коллекцию элементов по имени тега без учета пространства имен
all = XML.getElementsByTagName("MedicationPrescription");
length = all.length;

Для i = 0 по length - 1 Цикл
    Узел = all.item(i);
    СписокId = Узел.getElementsByTagName("id");
    Если СписокId.length > 0 Тогда
        Значение = СписокId.item(0).getAttribute("value");
        Сообщить("Значение ID: " + Значение);
    КонецЕсли;
КонецЦикла;

Способ 3. Использование функции local-name() в XPath

Ещё один вариант — обращение к локальному имени элемента с помощью XPath-функции local-name(). Важно учитывать, что при выборе дочерних элементов их также нужно запрашивать через local-name(), иначе выборка вернет пустое значение.

Рассмотрим пример кода:


XML = CreateObject("MSXML2.DOMDocument.6.0");
XML.Load("d:\файл.xml");

// Ищем теги по их локальному имени
all = XML.selectNodes("//*[local-name()='MedicationPrescription']");
length = all.length;

Для i = 0 по length - 1 Цикл
    Узел = all.item(i);
    // Дочерний узел выбираем аналогично по local-name()
    УзелId = Узел.selectSingleNode("*[local-name()='id']");
    Если ПустоеЗначение(УзелId) = 0 Тогда
        Значение = УзелId.getAttribute("value");
        Сообщить("Значение ID: " + Значение);
    КонецЕсли;
КонецЦикла;

Для повышения точности поиска можно дополнить условие проверкой пространства имен через функцию namespace-uri():


all = XML.selectNodes("//*[local-name()='MedicationPrescription' and namespace-uri()='http://hl7.org/fhir']");

Итоги

Наиболее стандартизированным решением при работе с DOM в 1С является регистрация пространства имен через setProperty("SelectionNamespaces", ...). В более простых сценариях разбора структуры XML подходят методы getElementsByTagName или использование local-name() в XPath-запросах.

← На главную