Преобразование XML в таблицу значений или иной объект 1С методом XSL преобразования

Сразу открою интригу, напрямую прочитать XML, не содержащий объект 1С, не удастся. Статья раскрывает способы привести XML к формату, который возможно прочитать средствами платформы.

Чтение и разбор формата 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. 

27 Comments

  1. w.r.

    На самом деле можно через

    ФабрикаXDTO.ПрочитатьXML(ЧтениеXML)

    если у тебя структура XML представляет собой таблицу с более чем с 1 строкой, то вернётся тебе объект СписокXDTO, по которому можно пройтись циклом Для каждого. И это без всякой схемы XLS

    Reply
  2. kraspila

    (1) если объект несложный и статичный, то такой метод тоже применим.

    Reply
  3. w.r.

    (2) если сложный, тогда лучше нарисовать XSD схему и с помощью неё уже делать преобразование. Но мне лично хватает ФабрикиXDTO без схемы. Потом просто работаешь со структурой объекта по именам полей

    Reply
  4. oleganatolievich

    а что по скорости?

    Reply
  5. kraspila

    (4) по скорости очень эффективно, но на больших файлах не тестировалось

    Reply
  6. oleganatolievich

    (5) да, видел такое преобразование в типовых. прикольно, сделали бы разрабы платформы 1С такое же, но платформенное, и чтобы на веб-клиентах и тонких клиентах всяких работало, не было бы им цены.

    Reply
  7. kraspila

    (6) это средствами платформы и делается, просто макет xsl надо написать

    Reply
  8. oleganatolievich

    (7) да, согласен, просто это муторно.

    Reply
  9. w.r.

    (7) причём если для создания XSD схемы в платформе есть инструмент, хоть и корявенький, в виде XDTO-пакета в конфигураторе, то для создания XSL схемы нет ничего

    Reply
  10. oleganatolievich

    (9) да что уж там десериализацию из JSON в вебклиенте не смогли. ну такое…

    Reply
  11. PerlAmutor

    (10) Тоже был в шоке, когда уже после реализации обработки, увидел, что «СериализаторXDTO.ПрочитатьJSON» не доступен в Web-клиенте:

    Доступность:
    
    Тонкий клиент, сервер, толстый клиент, внешнее соединение. 

    Технология пришедшая в 1С из Web, не работает в Web…

    Reply
  12. ktb

    (10)(11) Не могу себе представить сценарий, в котором нужно читать json на клиенте.

    Reply
  13. oleganatolievich

    (12) самое простое, делаю в поле HTML документа делаешь JSON.stringify, в 1с забираешь в событии при нажатии на поле HTML. мне кажется для расшифровки результата не надо постоянно лезть на сервер, это же интерфейс ёпт.

    Reply
  14. capitan

    (1)Согласен. Решение красивое, но мудреное.

    К тому же зачастую в xml бывает СписокXDTO, а бывает ОбъектXDTO в одном и том же месте.

    Тогда такое преобразование может и не взлететь.

    Reply
  15. kraspila

    (14) в том и прелесть что удалось миновать XDTO и сразу отправить всё в таблицу, в вашем частном случае мы получим таблицу с одной строкой. Решение дает нам устойчивость в том случае, если поставщик XML изменил его структуру.

    Reply
  16. capitan

    (15)Наверное да.

    Плюса в любом случае заслуживает )

    Reply
  17. starik-2005

    Статья плохая, но разбирается очень хорошая вещь. Я бы автору порекомендовал бы рассмотреть преобразование XSLT более развернуто, хотя многим действительно нужен кейс, даже такой примитивный.

    Reply
  18. w.r.

    (14) ОбъектXDTO когда количество строк <= 1, во всех остальных случаях будет СписокXDTO

    Reply
  19. w.r.

    (15) сомнительная прелесть рисовать для каждого отдельного случая XLS схемы. Намного проще XDTO разобрать

    Reply
  20. PLAstic

    Как написали в аналогичной теме 6 лет назад,

    Технология XSLT в вэбе, где и предполагалось основное применение, «не взлетела». Поддержка XSLT в браузерах появилась в IE6, и с тех пор не обновлялась лет десять. Год назад один из последних «могикан» — mail.ru отказалась от использования XSLT в своем почтовом сервисе.

    Желающих развивать эту технологию уже давно не наблюдается.

    Слабо представляю, какие уникальные выгоды от использования XSLT можно получить. Защита от изменения формата поставщиком? Так ведь для этого и нужны XSD-схемы. Пришедший пакет не читается? Пришло время лезть в текст и смотреть, что изменилось. Меняем схему XSD и логику анализа — и всё, работаем дальше.

    Reply
  21. A_Max

    Делал аналогичную загрузку, но для упрощения сделал «сериализацию» в массив структур.

    Удобно, что на выходе получается готовый 1Совский объект.

    Reply
  22. kraspila

    (21) задача ставилась сверить два XML файла по ключевым полям. Для этого хорошо подходит таблица.

    Reply
  23. A_Max

    (22) Я понимаю. Понятно, что зависит от задачи. Ну и по скорости очень порадовало.

    Вообще проводил анализ сериализованных представлений разных объектов и смотрел, что лучше подходит. Кстати очень полезно оказалось глянуть на табличный документ, для себя добавил функционал по сворачиванию/разворачиванию нужных групп.

    Reply
  24. kraspila

    (23) натолкнули меня на мысль, действительно, можно файлы просто привести к единому виду и сравнить, минуя любое преобразование. Это что касается моего прикладного случая

    Reply
  25. Olenevod

    Статьи уже были на эту тему, поэтому как бы совсем ничего нового, однако немного с другой стороны (возможно это тоже необходимо, чтобы это стало более понятным и как-то шло в массы).

    Но вот полезней было бы если некий конструктор простой был бы реализован, который позволяет создавать шаблоны XSLT.

    Reply
  26. fomix

    (22) XML файл — текст. 1С в режиме Предприятия либо Конфигуратора — «Сравнить файлы…». Либо простенькая обработка сравнения текстов — вот и все решение!

    Reply
  27. kraspila

    (26)

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *