Работа с XML в 1С через ПостроительDOM и методы ВычислитьВыражениеXPath часто вызывает затруднения у разработчиков. Основная сложность заключается в понимании контекста выполнения запроса и правильном построении путей. Давайте вместе разберем, почему ваши запросы могут возвращать Неопределено и как научиться уверенно парсить сложные структуры данных.
Первое, что необходимо усвоить: XPath чувствителен к контексту. Когда вы вызываете метод ВычислитьВыражениеXPath("путь", контекстныйУзел), второй параметр определяет точку отсчета. Если вы указываете путь, начинающийся с символа /, 1С всегда ищет элемент от самого корня документа, игнорируя ваш контекстныйУзел. Если вы хотите искать «внутри» текущего узла, используйте относительные пути.
Часто разработчики забывают, что XML может содержать вложенные пространства имен. Если в файле определены пространства имен, стандартный запрос без РазыменовательПространствИменDOM просто не найдет узлы, даже если путь написан верно.
Давайте проанализируем, как организовать корректный доступ к элементам. Чтобы перебрать повторяющиеся узлы, не стоит пытаться использовать ПолучитьСледующий() в бесконечном цикле, если вы не уверены в структуре набора. Используйте подход с перебором по количеству найденных узлов.
ЧтениеXML и создайте ДокументDOM.РазыменовательПространствИменDOM, чтобы избежать ошибок при поиске.Рассмотрим пример кода, который позволяет обойти структуру getInvoiceReply и извлечь данные из вложенных элементов invCar:
// Предполагаем, что Разыменователь уже создан
РезультатПоиска = ДокументDOM.ВычислитьВыражениеXPath("/getInvoiceReply/invCar", ДокументDOM, Разыменователь);
КоличествоУзлов = РезультатПоиска.Количество();
Для Индекс = 0 По КоличествоУзлов - 1 Цикл
ТекущийУзел = РезультатПоиска.ПолучитьУзел(Индекс);
// Теперь ищем номер вагона внутри конкретного узла invCar
ЗапросНомер = "./carNumber";
РезультатНомер = ДокументDOM.ВычислитьВыражениеXPath(ЗапросНомер, ТекущийУзел, Разыменователь);
Если РезультатНомер.Количество() > 0 Тогда
УзелНомер = РезультатНомер.ПолучитьУзел(0);
Сообщить("Номер вагона: " + УзелНомер.ТекстовоеСодержимое);
КонецЕсли;
КонецЦикла;
Ошибка Несоответствие типов (параметр номер '2') возникает чаще всего тогда, когда вы передаете в метод ВычислитьВыражениеXPath переменную, значение которой равно Неопределено. Это происходит, если предыдущий шаг поиска не нашел узел. Всегда добавляйте проверку:
Если ЭлементРодитель <> Неопределено Тогда
Результат = ДокументDOM.ВычислитьВыражениеXPath("путь", ЭлементРодитель, Разыменователь);
Иначе
// Обработка ситуации, когда родитель не найден
КонецЕсли;
Если структура XML, с которой вы работаете, заранее известна и является статической, рассмотрите возможность использования ФабрикаXDTO. ФабрикаXDTO позволяет провести десериализацию XML в структуру объектов 1С. Это избавляет от необходимости писать сложные XPath-запросы и делает код более читаемым и легким в поддержке.
Если же XML динамический или его структура заранее неизвестна, то XPath является отличным инструментом, но требует тщательного контроля за текущим контекстным узлом и обязательной проверки количества возвращаемых объектов перед обращением к ним через методы ПолучитьУзел().
Помните: всегда проверяйте регистр имен тегов. XML и XPath в 1С чувствительны к регистру, поэтому CarNumber и carNumber — это два разных узла.