Прочитать XML-атрибуты по имени и построить диагностическую таблицу

Учебные задачи

Индексы начинаются с нуля, но порядок атрибутов не является бизнес-контрактом. Для загрузки code/price/unit используем имена и URI.

Где и как запускать

Учебная база: создайте серверный общий модуль УчебныеЗадачи (флаг Сервер). Код без директив вставьте в тело процедуры ВыполнитьПример() Экспорт. Вызовите её из серверного обработчика команды учебной обработки. Не запускайте в рабочей базе.

Подготовка

  1. Документы и все узлы создаются в памяти на сервере. Внешние XML, DTD, сетевые схемы и файлы не загружаются.

  2. Сначала оставьте учебные имена и значения неизменёнными. После контрольного запуска меняйте по одному условию.

  3. В этом блоке каждый пример создаёт собственное дерево DOM в памяти. Файлы, сеть, данные документов и справочников не используются.

  4. Открыть у ЧтениеУзловDOM принимает узел, а у ЗаписьУзловDOM — документ-владелец будущих узлов. Это не открытие файла.

URI = "urn:guide:products";
URIЕдиниц = "urn:guide:units";
Документ = Новый ДокументDOM(URI, "g:product");
Корень = Документ.ЭлементДокумента;
Корень.УстановитьСоответствиеПространстваИмен("g", URI);
Корень.УстановитьСоответствиеПространстваИмен("m", URIЕдиниц);
Корень.УстановитьАтрибут("code", "A-01");
Корень.УстановитьАтрибут("price", "250");
АтрибутЕдиницы = Документ.СоздатьАтрибут(URIЕдиниц, "m:unit");
АтрибутЕдиницы.Значение = "шт";
Корень.УстановитьУзелАтрибута(АтрибутЕдиницы);
Корень.ДобавитьДочерний(Документ.СоздатьТекстовыйУзел("Книга"));
Чтение = Новый ЧтениеУзловDOM;
Чтение.Открыть(Документ);
Попытка
    Если Чтение.ПерейтиКСодержимому() <> ТипУзлаXML.НачалоЭлемента Тогда
        ВызватьИсключение "Ожидался собственный корневой элемент";
    КонецЕсли;
    Сообщить(Чтение.Имя = "g:product");
    Сообщить(Чтение.ЛокальноеИмя = "product");
    Сообщить(Чтение.Префикс = "g");
    Сообщить(Чтение.URIПространстваИмен = URI);
    Сообщить(Чтение.ЗначениеАтрибута("code") = "A-01");
    Сообщить(Чтение.ПолучитьАтрибут("price") = "250");
    Сообщить(Чтение.ЗначениеАтрибута("unit", URIЕдиниц) = "шт");
    Сообщить(Чтение.ПолучитьАтрибут("missing") = Неопределено);
    Диагностика = Новый ТаблицаЗначений;
    Диагностика.Колонки.Добавить("ПолноеИмя");
    Диагностика.Колонки.Добавить("ЛокальноеИмя");
    Диагностика.Колонки.Добавить("Префикс");
    Диагностика.Колонки.Добавить("URI");
    Диагностика.Колонки.Добавить("ТипАтрибута");
    Диагностика.Колонки.Добавить("Значение");
    Для Индекс = 0 По Чтение.КоличествоАтрибутов() - 1 Цикл
        СтрокаАтрибута = Диагностика.Добавить();
        СтрокаАтрибута.ПолноеИмя = Чтение.ИмяАтрибута(Индекс);
        СтрокаАтрибута.ЛокальноеИмя = Чтение.ЛокальноеИмяАтрибута(Индекс);
        СтрокаАтрибута.Префикс = Чтение.ПрефиксАтрибута(Строка(Индекс));
        СтрокаАтрибута.URI = Чтение.URIПространстваИменАтрибута(Индекс);
        СтрокаАтрибута.ТипАтрибута = Чтение.ТипАтрибута(Индекс);
        СтрокаАтрибута.Значение = Чтение.ЗначениеАтрибута(Индекс);
        Сообщить(СтрокаАтрибута.ПолноеИмя + " = " + СтрокаАтрибута.Значение);
    КонецЦикла;
    Сообщить(Диагностика.Количество() = Чтение.КоличествоАтрибутов());
    Сообщить(Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента);
Исключение
    Чтение.Закрыть();
    ВызватьИсключение;
КонецПопытки;
Чтение.Закрыть();

Разбор по шагам

  1. ПерейтиКСодержимому ставит чтение на начало product; только после этого обращаемся к его атрибутам.

  2. Именованные варианты отличают отсутствие атрибута (Неопределено) от пустого значения существующего атрибута.

  3. Для диагностики обходятся все индексы. В поле ПрефиксАтрибута индекс передаём строкой согласно сигнатуре локальной справки 8.5; остальные индексные методы принимают число.

  4. Индексные методы и ПолучитьАтрибут/ЗначениеАтрибута читают данные без перехода на атрибут. В конце текущий узел всё ещё НачалоЭлемента.

Как проверить результат

  1. Десять логических проверок дают Истина.

  2. Диагностика содержит code=A-01, price=250, m:unit=шт. Не требуйте конкретного порядка строк; определения пространств имён рассматривайте отдельно от бизнес-атрибутов.

  3. price возвращается строкой 250, не числом: преобразование числа и валидация внешнего ввода — отдельная задача.

Ожидаемый результат

Атрибуты извлечены без изменения позиции и без предположений об их порядке.

На что обратить внимание

  1. Сначала проверяйте тип узла. Доступ к атрибутам текста или конца элемента не является чтением атрибутов предыдущего товара.

  2. Не ищите unit только по буквам m:unit, если префикс может измениться: используйте локальное имя и URI.

  3. Для недоверенных XML проверяйте обязательность, формат, длину и допустимость каждого бизнес-значения.

Пример не запускался в вашей базе. Перед применением проверьте его в указанном учебном контексте.

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.