Для решения этой проблемы я сделал обработку, которая на основе исходного "шаблона" и данных формирует выходной XML, который может быть и HTML’ем запросто :).
Также эта обработка решает проблему формирования отчетов в html, например для рассылки их по почте.
На вход к шаблону подается структура с данными. Данные хранятся в полях структуры. Данные могут содержать таблицы значений и массивы — тогда с помощью языка шаблонов можно вывести в HTML список или таблицу.
Язык шаблонов описан в самой обработке, но на всякий случай пробегусь по нему.
Описание языка шаблонов версии 002. Относительно версии 001 появилась возможность указывать области, которые не выводятся, если в структуре нет переменной.
Вывод переменной
<var name="ИмяПеременной"/>
Тег var заменяется на XML представление этой переменной. Таким образом на месте ссылок выводится уникальтный идентификатор, если надо выводить предстваление, сделует об этом позаботится в блоке заполенния даных. Если ИмяПеременной отсутствует в данных, или оно равно Неопределено, то тег просто вырежется.
Опциональный вывод области
<area name="ИмяПеременной">Содержимое области, в т.ч. поля, списки, другие области</area>
Если ИмяПеременной отсутствует в данных, или оно равно Неопределено, то тег просто вырежется, в остальгных случаях содержимое тега будет заполнено ву соответствии с шаблоном.
Вывод коллекции
<list name="ИмяПеременной">
Произвольный кусок шаблона, в т.ч. включающий другий списки, области, переменные
<repeat>часть шаблона, которая будет повторена и заполнена в контексте элемента коллекции <var name="ИмяПоляКоллекции"/>, тут также могут быть выведены списки, области, поля</repeat>
Произвольный кусок шаблона, в т.ч. включающий другий списки, области, переменные
</list>
Вывод коллекции (массива структур или таблицы значений) осуществляется на месте тега list. В случае пустой коллекции — тег будет просто вырезан. Часть шаблона <repeat>…<repeat> будет заполнена по правилам шаблона, но доступны будут не только поля более верхних уровней структуры, но и поля конкретного элементв коллекции. Для массива структур — это поля структур-элементов массива, для таблицы значений — колонки таблицы значений.
Вывод вложенной структуры
<struct name="ИмяПеременной">
Произвольный кусок шаблона, в т.ч. включающий другий списки, области, переменные, в т.ч. в контексте структуры ИмяПеременной
</struct>
Вывод вложенной структуры похож на вывод списка. Также если структура пустая — тег будет просто вырезан, также внутри структуры доступны все поля самой структуры, а также все поля верхних уровней структуры данных, из которой заполняется шаблон.
Обработка заполнения поддерживает произвольную вложенность шаблонов друг в друга, т.е. может быть структура с массивом структур, у которой в полях другие структуры или таблицы значений. Единственное, с чем нужно быть осторожным — это с именами полей — если они повторяются внутри иерархии (т.е. на верхнем уровене есть поле «Номенклатура» и внутри одной из вложенных структур также есть поле «номенклатура») то нет гарантии, что в нужное место выведется поле с того уровня иерархии, который создатель шаблона имеет ввиду. Так происходит из-за того, что обход идет без предварительной сортировки по глубине вложенности. Для того, чтобы быть уверенным в результате — полям лучше давать имена, уникальные по всей структуре вложенности.
Обработка содержит в себе функции для заполнения шаблона, а также интерфейс для генерации данных для шаблона, самого шаблона и просмотра результата заполнения шаблона на основе сформированных данных.
Также по кнопке «Установить шаблон и модуль из макетов» шаблон и модуль для генерации данных будут заполены примером, поясняющим все варианты использования языка шаблона.