Программное создание xml (а можно и HTML) на основе xml схемы (XSD), через фабрику XDTO

Публикация № 1062859

Разработка - Системная интеграция - Обмен через XML

XDTO ОбъектXDTO СписокXDTO ФабрикаXDTO ПакетXDTO XML HTML XSD Схема htmlbook обмен сериализация

43
Объект XDTO, Фабрика XDTO, ПакетXDTO - как же это все сложно, или нет?

Warning

Данная статья не претендует на оригинальность и не является конечным решением.

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

 

Разработчику решений на 1С, какова не была бы его судьба, рано или поздно все равно придется иметь дело с XDTO. Самое простое это считать XML:

// прочитали
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(XMLСтрока);
ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
ЧтениеXML.Закрыть();

Теперь ко всем элементам и атрибутам можно обращаться через точку, где объект XDTO приблизительно представляет собой структуру из массивов и структур.

Неплохо. Но как этот самый объект построить с нуля и записать? Об этом и пойдет речь ниже!

План для построения Объекта XDTO с нуля:

  1. XML схема, она же XSD.
  2. Загрузить ее в фабрику XDTO;
  3. Получить комплексный тип корневого элемента;
  4. Создать новый ОбъектXDTO;
  5. Инициализировать его свойства (и свойства его свойств);
  6. Заполнить объект xdto;
  7. Преобразовать в строку XML.

Демонстрационная реализация на основе построения HTML для вывода таблицы значений:

Xml схема набросанная в oxygen xml editor:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:tns="http://htmlbook.ru/html" xmlns:xs="http://www.w3.org/2001/XMLSchema"
	targetNamespace="http://htmlbook.ru/html" attributeFormDefault="unqualified"
	elementFormDefault="qualified" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning">
	<xs:attributeGroup name="MetaValue">
		<xs:attribute name="charset" type="xs:string"/>
		<xs:attribute name="content" type="xs:string"/>
	</xs:attributeGroup>
	<xs:element name="BODY">
		<xs:complexType>
			<xs:sequence>
				<xs:any namespace="##any"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	<xs:element name="HEAD">
		<xs:complexType>
			<xs:sequence>
				<xs:element maxOccurs="unbounded" minOccurs="0" name="meta">
					<xs:complexType>
						<xs:attributeGroup ref="tns:MetaValue"/>
					</xs:complexType>
				</xs:element>
				<xs:element minOccurs="0" name="Title" type="xs:string"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	<xs:complexType name="Table">
		<xs:sequence>
			<xs:element name="Caption" type="xs:string"/>
			<xs:element name="TR" maxOccurs="unbounded" minOccurs="0">
				<xs:complexType>
					<xs:sequence>
						<xs:element name="TH" minOccurs="0" maxOccurs="unbounded" type="xs:string"> </xs:element>
						<xs:element name="TD" minOccurs="0" maxOccurs="unbounded" type="xs:string">
						</xs:element>
					</xs:sequence>
				</xs:complexType>
			</xs:element>
		</xs:sequence>
		<xs:attribute default="1" name="border"/>
	</xs:complexType>
	<xs:complexType name="HTML">
		<xs:sequence>
			<xs:element ref="tns:HEAD"> </xs:element>
			<xs:element ref="tns:BODY"/>
		</xs:sequence>
	</xs:complexType>
</xs:schema>
 
 Визуальное представление схемы:

Код конструктора:

&НаСервереБезКонтекста
Функция ОбъектXDTOВXML(ОбъектXDTO, Фабрика)
	ЗаписьXML = Новый ЗаписьXML;
	ЗаписьXML.УстановитьСтроку("UTF-8");
	Фабрика.ЗаписатьXML(ЗаписьXML, ОбъектXDTO);
	Возврат ЗаписьXML.Закрыть();
КонецФункции

&НаСервере
Функция ПолучитьТипСвойтваXDTO(ОбъектXDTO, ИмяСвойтва)
	Возврат ОбъектXDTO.Свойства().Получить(ИмяСвойтва).Тип;
КонецФункции

&НаСервере
Функция ИнициализироватьСвойствоXDTO(ОбъектXDTO, Фабрика, ИмяСвойтва) Экспорт
	
	ТипСвойтваXDTO = ПолучитьТипСвойтваXDTO(ОбъектXDTO, ИмяСвойтва);
	Если ТипСвойтваXDTO <> Неопределено Тогда
		ОбъектXDTO[ИмяСвойтва] = Фабрика.Создать(ТипСвойтваXDTO);
		Возврат ОбъектXDTO[ИмяСвойтва];
	Иначе
		Возврат Неопределено;
	КонецЕсли;
	
КонецФункции

&НаСервере
Функция ТаблицуЗначенийВHTML(ТаблицаДанных)
	
	// файл для загрзки xml схемы
	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("XSD");
	// запишем содержимое схемы
	РеквизитФормыВзначение("Объект").ПолучитьМакет("html_xsd").Записать(ИмяВременногоФайла, "utf-8");
	// новая фабрика с импортированной схемой
	Фабрика = СоздатьФабрикуXDTO(ИмяВременногоФайла);
	// если схема была импортирована в конфигурацию как пакет XDTO то код выше ненужен.
	// достаточно лишь фабрика = ФабрикаXDTO;

	// новый пустой xdto
	ОбъектHTML = Фабрика.Создать(Фабрика.Тип("http://htmlbook.ru/html", "HTML"));
	// получить тиип head
	ОбъектHead = ИнициализироватьСвойствоXDTO(ОбъектHTML, Фабрика, "head");
	// установим описание страницы
	ОбъектHead.Title = "ТаблицаДанных";
	// элемент списка meta
	ТипЭлементаMeta = ПолучитьТипСвойтваXDTO(ОбъектHead, "meta");
	// создать элемент meta
	ОбъектMeta = Фабрика.Создать(ТипЭлементаMeta);
	// установим кодировку html
	ОбъектMeta.charset = "UTF-8";
	// добавить элемент в список
	ОбъектHead.Meta.Добавить(ОбъектMeta);
	// получим объект body
	ОбъектBody = ИнициализироватьСвойствоXDTO(ОбъектHTML, Фабрика, "body");
	// создать таблицу
	ОбъектTable = Фабрика.Создать(Фабрика.Тип("http://htmlbook.ru/html", "Table"));
	// добавить таблицу в body
	ОбъектBody.Добавить(ФормаXML.Элемент, "http://htmlbook.ru/html", "Table", ОбъектTable); 
	// зададим имя таблици
	ОбъектTable.Caption = "ТаблицаДанных";
	// установим границу между ячейками
	ОбъектTable.Border = "1";
	
	// получим базовые типы списков
	ТипTR = ПолучитьТипСвойтваXDTO(ОбъектTable, "tr");
	ОбъектTR = Фабрика.Создать(ТипTR);
	ТипTD = ПолучитьТипСвойтваXDTO(ОбъектTR, "td");
	ТипTH = ПолучитьТипСвойтваXDTO(ОбъектTR, "th");
	
	// установим имена колонок
	ОбъектTable.TR.Добавить(ОбъектTR);
	Для Каждого КолонкаТаблицы Из ТаблицаДанных.Колонки Цикл
		ОбъектTH = Фабрика.Создать(ТипTH, КолонкаТаблицы.Имя);
		ОбъектTR.TH.Добавить(ОбъектTH);
	КонецЦикла;
	
	// установим значения строк
	Для Каждого СтрокаТаблицы Из ТаблицаДанных Цикл
		ОбъектTR = Фабрика.Создать(ТипTR);
		ОбъектTable.TR.Добавить(ОбъектTR);
		Для Каждого ЯчейкаТаблици Из СтрокаТаблицы Цикл
			ОбъектTD = Фабрика.Создать(ТипTD, Строка(ЯчейкаТаблици));
			ОбъектTR.TD.Добавить(ОбъектTD);
		КонецЦикла;
	КонецЦикла;

	// выполнить валидацию 
	Попытка
		ОбъектHTML.Проверить();
	Исключение
		Сообщить(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
	КонецПопытки;

	Возврат ОбъектXDTOВXML(ОбъектHTML, Фабрика);
	
КонецФункции

Сразу отвечу на вопрос, в чем заключается разница между пакетом XDTO и XML схемой? Если речь идет о создании объекта XDTO, то разницы нет, внешнюю схему, в отличие от пакета, изменять и сохранять проще.

Плюсы данного подхода:

  • Можно взять одну или несколько XSD Схем, подкорректировать под 1С и строить XML;
  • Можно стоить простые html странички;
  • Валидация - использование схемы, дает куда больше шансов, что во время разработки программист не забудет какой- нибудь тег или атрибут. 

 

43

См. также

Специальные предложения

Лучшие комментарии
1. Поручик 4315 20.05.19 11:18 Сейчас в теме
Судьба Онегина хранила (С) Наше Всё.
Мне до сих пор не пришлось иметь дело с XDTO, но в копилку добавил.
Deslime; YPermitin; Eret1k; +3 1 Ответить
Остальные комментарии
Избранное Подписка Сортировка: Древо
1. Поручик 4315 20.05.19 11:18 Сейчас в теме
Судьба Онегина хранила (С) Наше Всё.
Мне до сих пор не пришлось иметь дело с XDTO, но в копилку добавил.
Deslime; YPermitin; Eret1k; +3 1 Ответить
5. starik-2005 1942 21.05.19 09:24 Сейчас в теме
(1) да ничего там в этом ХДТО нет такого - просто объектная модель XML. Схема определяет совокупность объектов и их свойств. Сами объекты ХДТО могут содержать другие объекты в качестве свойств полей. Я как-то писал о том, как можно загрузить XML в дерево значений или выгрузить иерархический справочник в XML - вот там как раз все через ХДТО.
2. veri123 20.05.19 15:34 Сейчас в теме
Автор перевернул мой взгляд на мир.
Долго думал как оно работает.
Осознал что html от xml отличается только тем что теги фиксированы.
YPermitin; Eret1k; +2 Ответить
4. awk 692 21.05.19 09:19 Сейчас в теме
(2) Не только. В html незакрытые теги (<p>< br ></p>) использовать можно, а в xml нельзя
starik-2005; +1 Ответить
6. starik-2005 1942 21.05.19 09:25 Сейчас в теме
(2)
Осознал что html от xml отличается только тем что теги фиксированы.
В html необязательно закрывать тег, потому html не всегда можно прочитать в фабрику - придется его немного покромсать, о чем я тоже как-то писал.
9. Evil Beaver 6247 21.05.19 19:45 Сейчас в теме
(2)
Осознал что html от xml отличается только тем что теги фиксированы.

НЕЕТ! Отличаются смыслом и наполнением! А за теги html, написанные КАПСЛОКОМ автору - порицание и бесплатная путевка в 2019 год из его 1999-го!
3. awk 692 21.05.19 09:17 Сейчас в теме
Сразу отвечу на вопрос, в чем заключается разница между пакетом XDTO и XML схемой?


Если хотите использовать аннотации, например для автогенерации документации (xsddoc), то забудьте про XDTO.
7. ntemny 51 21.05.19 12:23 Сейчас в теме
Автору. Вообще xml в html проще и быстрее через ПреобразованиеXSL делать. Достаточно сериализовать объект а потом через преобразование выдать в html строку.
8. Evil Beaver 6247 21.05.19 19:43 Сейчас в теме
Привести вам ссылки на мои 3 статьи по XDTO или не надо? :D
10. Eret1k 598 21.05.19 20:15 Сейчас в теме
(8) Infostart уникальная площадка для того, чтобы делиться опытом.
И более того, каждый может делиться для своего уровня.

P.S. Прочитал статьи 3, круто.
11. caponid 23.05.19 09:30 Сейчас в теме
(8) Не надо, они и так есть в закладках))

А вот эта статья очень понравилась как легкостью изложения, так и изящностью идеи примера.
Автору респект.
12. rudnitskij 24.05.19 13:54 Сейчас в теме
Функция ОбъектXDTOВXML(ОбъектXDTO, Фабрика)

Мне одному кажется, что имя этой же функции в виде
ОбъектXDTO_В_XML
было бы более наглядным и легче читаемым?
Оставьте свое сообщение