Чтение и разбор формата XML при разработке в 1С довольно часто встречающаяся задача. Механизмы платформы дают для этого несколько вариантов реализации. Например, чтение DOM модели документа и последовательный разбор его в коде. Я же буду рассматривать более универсальный метод, основанный на приведении входящего файла к стандарту, пригодного для сериализации в объект 1С средствами платформы.
Ключевым элементом этого процесса является схема преобразования XSL. По стандарту языка XSL написано много статей, я рекомендую перед дальнейшим прочтением ознакомиться с некоторыми из них, а так же изучить спецификацию формата XPath .
Итак, имеем некий XML, который мы хотим прочитать в таблицу, или иной объект 1С.
<?xml version="1.0" encoding="UTF-8"?>
<eDIMessage id="e6418b61-b40e-4e3f-b0c5-4f2596еd93f6" creationDateTime="2024-10-15T14:38:39Z">
<correctiveInvoice number="10-0000057" date="2024-10-01" type="Original">
<lineItems>
<lineItem>
<gtin>4670005047988</gtin>
<description>ЦВЕТЫ СПАТИФИЛЛУМ</description>
</lineItem>
<lineItem>
<gtin>4607015058314</gtin>
<description>ЦВЕТЫ ФИАЛКА МИКС</description>
</lineItem>
</lineItems>
</correctiveInvoice>
</eDIMessage>
В данном файле нас интересует табличная часть, заключенная в тэги <LineItem>. Для доступа к этой части будем использовать выражение xPath:
eDIMessage/correctiveInvoice/lineItems/lineItem
Это выражение будет являться основой схемы XLS
"<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<ValueTable xmlns="http://v8.1c.ru/8.1/data/core" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<column>
<Name xsi:type="xs:string">Колонка1</Name>
<ValueType/>
</column>
<column>
<Name xsi:type="xs:string">Колонка2</Name>
<ValueType/>
</column>
<xsl:for-each select="eDIMessage/correctiveInvoice/lineItems/lineItem">
<row>
<Value xsi:type="xs:string">
<xsl:value-of select="gtin"/>
</Value>
<Value xsi:type="xs:string">
<xsl:value-of select="description"/>
</Value>
</row>
</xsl:for-each>
</ValueTable>
</xsl:template>
</xsl:stylesheet>"
Структура этой схемы скопирована с файла выгрузки 1С, содержащим сериализованую табличную часть, однако в нее добавлена инструкция процессору XML for-each, запускающая цикл перебора строк табличной части исходного файла, по указанному пути и инструкции value-of, которые выводят в цикл содержимое указанных тегов, в данном случае gtin и description.
Ниже приводится функция 1С, к которую в качестве параметров передается исходный документ XML и схема преобразования в виде строки.
Функция ПреобразоватьXMLвТЗ(СтрокаXML, СхемаПреобразования);
ПроцессорПреобразования = Новый ПреобразованиеXSL;
ПроцессорПреобразования.ЗагрузитьИзСтроки(СхемаПреобразования);
РезультатПреобразованияXML = ПроцессорПреобразования.ПреобразоватьИзСтроки(СтрокаXML);
ЧтениеXML = Новый ЧтениеXML();
ЧтениеXML.УстановитьСтроку(РезультатПреобразованияXML);
ТЗ = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Возврат ТЗ;
КонецФункции
функция возвращает таблицу значений, с колонками "Колонка1" и "Колонка2", в строках содержащие значения тегов gtin и description.
На самом деле можно через
если у тебя структура XML представляет собой таблицу с более чем с 1 строкой, то вернётся тебе объект СписокXDTO, по которому можно пройтись циклом Для каждого. И это без всякой схемы XLS
(1) если объект несложный и статичный, то такой метод тоже применим.
(2) если сложный, тогда лучше нарисовать XSD схему и с помощью неё уже делать преобразование. Но мне лично хватает ФабрикиXDTO без схемы. Потом просто работаешь со структурой объекта по именам полей
а что по скорости?
(4) по скорости очень эффективно, но на больших файлах не тестировалось
(5) да, видел такое преобразование в типовых. прикольно, сделали бы разрабы платформы 1С такое же, но платформенное, и чтобы на веб-клиентах и тонких клиентах всяких работало, не было бы им цены.
(6) это средствами платформы и делается, просто макет xsl надо написать
(7) да, согласен, просто это муторно.
(7) причём если для создания XSD схемы в платформе есть инструмент, хоть и корявенький, в виде XDTO-пакета в конфигураторе, то для создания XSL схемы нет ничего
(9) да что уж там десериализацию из JSON в вебклиенте не смогли. ну такое…
(10) Тоже был в шоке, когда уже после реализации обработки, увидел, что «СериализаторXDTO.ПрочитатьJSON» не доступен в Web-клиенте:
Технология пришедшая в 1С из Web, не работает в Web…
(10)(11) Не могу себе представить сценарий, в котором нужно читать json на клиенте.
(12) самое простое, делаю в поле HTML документа делаешь JSON.stringify, в 1с забираешь в событии при нажатии на поле HTML. мне кажется для расшифровки результата не надо постоянно лезть на сервер, это же интерфейс ёпт.
(1)Согласен. Решение красивое, но мудреное.
К тому же зачастую в xml бывает СписокXDTO, а бывает ОбъектXDTO в одном и том же месте.
Тогда такое преобразование может и не взлететь.
(14) в том и прелесть что удалось миновать XDTO и сразу отправить всё в таблицу, в вашем частном случае мы получим таблицу с одной строкой. Решение дает нам устойчивость в том случае, если поставщик XML изменил его структуру.
(15)Наверное да.
Плюса в любом случае заслуживает )
Статья плохая, но разбирается очень хорошая вещь. Я бы автору порекомендовал бы рассмотреть преобразование XSLT более развернуто, хотя многим действительно нужен кейс, даже такой примитивный.
(14) ОбъектXDTO когда количество строк <= 1, во всех остальных случаях будет СписокXDTO
(15) сомнительная прелесть рисовать для каждого отдельного случая XLS схемы. Намного проще XDTO разобрать
Как написали ваналогичной теме 6 лет назад,
Желающих развивать эту технологию уже давно не наблюдается.
Слабо представляю, какие уникальные выгоды от использования XSLT можно получить. Защита от изменения формата поставщиком? Так ведь для этого и нужны XSD-схемы. Пришедший пакет не читается? Пришло время лезть в текст и смотреть, что изменилось. Меняем схему XSD и логику анализа — и всё, работаем дальше.
Делал аналогичную загрузку, но для упрощения сделал «сериализацию» в массив структур.
Удобно, что на выходе получается готовый 1Совский объект.
(21) задача ставилась сверить два XML файла по ключевым полям. Для этого хорошо подходит таблица.
(22) Я понимаю. Понятно, что зависит от задачи. Ну и по скорости очень порадовало.
Вообще проводил анализ сериализованных представлений разных объектов и смотрел, что лучше подходит. Кстати очень полезно оказалось глянуть на табличный документ, для себя добавил функционал по сворачиванию/разворачиванию нужных групп.
(23) натолкнули меня на мысль, действительно, можно файлы просто привести к единому виду и сравнить, минуя любое преобразование. Это что касается моего прикладного случая
Статьи уже были на эту тему, поэтому как бы совсем ничего нового, однако немного с другой стороны (возможно это тоже необходимо, чтобы это стало более понятным и как-то шло в массы).
Но вот полезней было бы если некий конструктор простой был бы реализован, который позволяет создавать шаблоны XSLT.
(22) XML файл — текст. 1С в режиме Предприятия либо Конфигуратора — «Сравнить файлы…». Либо простенькая обработка сравнения текстов — вот и все решение!
(26)