Как распарсить произвольный XML файл в 1С

1. BuryMeInVegas 14.10.20 14:22 Сейчас в теме
Добрый день! Есть ли возможность написания универсальной обработки для чтения и разбора ЛЮБОГО xml файла? Иными словами, гибкая процедура, которая бы распарсила абсолютно произвольный xml файл, который бы мы в неё залили.
По теме из базы знаний
Найденные решения
12. VictorRGB2 13 14.10.20 17:05 Сейчас в теме
чтобы вот прямо любую xml подсунули и процедура вам правильно ее разобрала, это утопия, ИМХО
в любой xml есть структура - секции, теги, атрибуты, значения тегов или атрибутов
не зная структуры заранее нельзя разобрать ее правильно
вернее можно... но для этого в самой xml должно присутствовать описание типов значений атрибутов\тегов, чтобы понимать к каком типу все это дело приводить в 1С
можно, конечно, все в строку пихать, но потом все равно придется результат вручную обрабатывать скорее всего

вот так примерно можно прочитать можно любую xml (выдернуто из контекста, могут быть ошибки, но смысл должен быть понятен)
лДокументXML = СоздатьОбъект("MSXML2.DOMDocument.4.0");
лДокументXML.Load(ПолноеИмяФайлаXML);

// надо знать как минимум имя корневого узла в xml и имена секций объектов
// ИмяКорневогоУзлаXML 
// ИмяТипаОбъектовXML

лКорневойУзел = лДокументXML.selectSingleNode(ИмяКорневогоУзлаXML);
лНаборОбъектовXML = лКорневойУзел.selectSingleNode(ИмяТипаОбъектовXML).childNodes();

Если лНаборОбъектовXML.Length() = 0 Тогда
	Продолжить;
КонецЕсли;
				
Для лНомерОбъекта = 1 По лНаборОбъектовXML.length() Цикл
	лОбъектXML = лНаборОбъектовXML.item(лНомерОбъекта - 1);

	//реквизиты XML-объекта
	лРеквизитыОбъектаXML = лОбъектXML.childNodes();

	Для лНомерСвойства = 1 По лРеквизитыОбъектаXML.length() Цикл
		лРеквизитОбъектаXML = лРеквизитыОбъектаXML.item(лНомерСвойства - 1);
						
		лИмяРеквизитаXML = лРеквизитОбъектаXML.nodeName;
		лЗначениеXML     = лРеквизитОбъектаXML.text;
						
		//реквизит XML-объекта
		лНомерСтрокиРеквизита = "";
			// знаем тип значения, приводим к известному типу лТипДанных
			// не знаем тип значения, приведем к строке, например, лТипДанных = Строка(100)
			лЗначениеРеквизита = ПривестиЗначениеКТипуИзXML(лЗначениеXML, лТипДанных); 

			//дочерний набор объектов XML-объекта
			Если лРеквизитОбъектаXML.childNodes().length() <> 0 Тогда
				лСЗнИменаДочернихТиповОбъектовXML.ДобавитьЗначение(лИмяРеквизитаXML);
			Иначе
				Продолжить;
			КонецЕсли;
							
			//дочерние типы XML-объектов
			Для р = 1 По лСЗнИменаДочернихТиповОбъектовXML.РазмерСписка() Цикл
				лИмяДочернегоТипаОбъектовXML = лСЗнИменаДочернихТиповОбъектовXML.ПолучитьЗначение(р);
				лДочернийТипОбъектовXML = лОбъектXML.selectSingleNode(лИмяДочернегоТипаОбъектовXML);
						
				лДочерниеОбъектыXML = лДочернийТипОбъектовXML.childNodes();
				Для лНомерДочернегоОбъектаXML = 1 По лДочерниеОбъектыXML.length() Цикл
					лДочернийОбъектXML = лДочерниеОбъектыXML.item(лНомерДочернегоОбъектаXML - 1);

					лРеквизитыДочернегоОбъектаXML = лДочернийОбъектXML.childNodes();
					Для лНомерДочернегоСвойства = 1 По лРеквизитыДочернегоОбъектаXML.length() Цикл
						лИмяДочернегоРеквизитаXML = лРеквизитыДочернегоОбъектаXML.item(лНомерДочернегоСвойства - 1).nodeName;
						лЗначениеДочернегоXML     = лРеквизитыДочернегоОбъектаXML.item(лНомерДочернегоСвойства - 1).text;
								
						//реквизит XML-объекта
						// знаем тип значения, приводим к известному типу лТипДанных
						// не знаем тип значения, приведем к строке, например, лТипДанных = Строка(100)
						лЗначениеДочернегоРеквизита = ПривестиЗначениеКТипуИзXML(лЗначениеДочернегоXML, лТипДанных);

					КонецЦикла; 
				КонецЦикла; 
			КонецЦикла; 

	КонецЦикла;
Показать
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. platonov.e 158 14.10.20 14:33 Сейчас в теме
Перем XDTO, ЧтениеXML;
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл("ПолныйПутьКФайлу.xml");
XDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
3. FatPanzer 14.10.20 14:36 Сейчас в теме
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ИмяФайла);
				
ПостроительDOM = Новый ПостроительDOM;
Результат = ПостроительDOM.Прочитать(ЧтениеXML);
				
ЧтениеXML.Закрыть();
4. FatPanzer 14.10.20 14:36 Сейчас в теме
Т.е. смотря что вы подразумеваете под результатом такого парсинга...
5. XAKEP 14.10.20 14:42 Сейчас в теме
https://infostart.ru/public/311011/

Разбор XML документа - почти все возможные способы


----------------
7. andy_zhav 197 14.10.20 15:11 Сейчас в теме
(1) Все уже придумано до нас:

ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ИмяФайла);
Результат = ПрочитатьXML(ЧтениеXML);


Ну и выдержка из СП:
ПрочитатьXML (ReadXML)
Синтаксис:
ПрочитатьXML(<ЧтениеXML>, <ТипЗначения>)
<ТипЗначения> (необязательный)
Тип: Тип.
Тип значения, которое должно быть прочитано из XML.
Если тип не указан, то будет произведена попытка определения типа значения непосредственно из представления XML.
Возвращаемое значение:
Тип: Значение считанного типа, Неопределено.
Описание:
Считывает значение в формате XML. Прочитаны могут быть значения тех типов, которые могут быть записаны методом ЗаписатьXML.
8. FatPanzer 14.10.20 15:13 Сейчас в теме
(7) А если это просто XML, не привязанный никоим образом к типам 1С?
9. user1464234 14.10.20 15:15 Сейчас в теме
А если это вообще текст, похожий на xml? Его можно обычным текстом читать?
11. FatPanzer 14.10.20 15:17 Сейчас в теме
(9) Читайте... Текст он и есть текст.
user1464234; +1 Ответить
10. andy_zhav 197 14.10.20 15:15 Сейчас в теме
(8) под типами 1с подразумевается коллекция в виде массива и структура
12. VictorRGB2 13 14.10.20 17:05 Сейчас в теме
чтобы вот прямо любую xml подсунули и процедура вам правильно ее разобрала, это утопия, ИМХО
в любой xml есть структура - секции, теги, атрибуты, значения тегов или атрибутов
не зная структуры заранее нельзя разобрать ее правильно
вернее можно... но для этого в самой xml должно присутствовать описание типов значений атрибутов\тегов, чтобы понимать к каком типу все это дело приводить в 1С
можно, конечно, все в строку пихать, но потом все равно придется результат вручную обрабатывать скорее всего

вот так примерно можно прочитать можно любую xml (выдернуто из контекста, могут быть ошибки, но смысл должен быть понятен)
лДокументXML = СоздатьОбъект("MSXML2.DOMDocument.4.0");
лДокументXML.Load(ПолноеИмяФайлаXML);

// надо знать как минимум имя корневого узла в xml и имена секций объектов
// ИмяКорневогоУзлаXML 
// ИмяТипаОбъектовXML

лКорневойУзел = лДокументXML.selectSingleNode(ИмяКорневогоУзлаXML);
лНаборОбъектовXML = лКорневойУзел.selectSingleNode(ИмяТипаОбъектовXML).childNodes();

Если лНаборОбъектовXML.Length() = 0 Тогда
	Продолжить;
КонецЕсли;
				
Для лНомерОбъекта = 1 По лНаборОбъектовXML.length() Цикл
	лОбъектXML = лНаборОбъектовXML.item(лНомерОбъекта - 1);

	//реквизиты XML-объекта
	лРеквизитыОбъектаXML = лОбъектXML.childNodes();

	Для лНомерСвойства = 1 По лРеквизитыОбъектаXML.length() Цикл
		лРеквизитОбъектаXML = лРеквизитыОбъектаXML.item(лНомерСвойства - 1);
						
		лИмяРеквизитаXML = лРеквизитОбъектаXML.nodeName;
		лЗначениеXML     = лРеквизитОбъектаXML.text;
						
		//реквизит XML-объекта
		лНомерСтрокиРеквизита = "";
			// знаем тип значения, приводим к известному типу лТипДанных
			// не знаем тип значения, приведем к строке, например, лТипДанных = Строка(100)
			лЗначениеРеквизита = ПривестиЗначениеКТипуИзXML(лЗначениеXML, лТипДанных); 

			//дочерний набор объектов XML-объекта
			Если лРеквизитОбъектаXML.childNodes().length() <> 0 Тогда
				лСЗнИменаДочернихТиповОбъектовXML.ДобавитьЗначение(лИмяРеквизитаXML);
			Иначе
				Продолжить;
			КонецЕсли;
							
			//дочерние типы XML-объектов
			Для р = 1 По лСЗнИменаДочернихТиповОбъектовXML.РазмерСписка() Цикл
				лИмяДочернегоТипаОбъектовXML = лСЗнИменаДочернихТиповОбъектовXML.ПолучитьЗначение(р);
				лДочернийТипОбъектовXML = лОбъектXML.selectSingleNode(лИмяДочернегоТипаОбъектовXML);
						
				лДочерниеОбъектыXML = лДочернийТипОбъектовXML.childNodes();
				Для лНомерДочернегоОбъектаXML = 1 По лДочерниеОбъектыXML.length() Цикл
					лДочернийОбъектXML = лДочерниеОбъектыXML.item(лНомерДочернегоОбъектаXML - 1);

					лРеквизитыДочернегоОбъектаXML = лДочернийОбъектXML.childNodes();
					Для лНомерДочернегоСвойства = 1 По лРеквизитыДочернегоОбъектаXML.length() Цикл
						лИмяДочернегоРеквизитаXML = лРеквизитыДочернегоОбъектаXML.item(лНомерДочернегоСвойства - 1).nodeName;
						лЗначениеДочернегоXML     = лРеквизитыДочернегоОбъектаXML.item(лНомерДочернегоСвойства - 1).text;
								
						//реквизит XML-объекта
						// знаем тип значения, приводим к известному типу лТипДанных
						// не знаем тип значения, приведем к строке, например, лТипДанных = Строка(100)
						лЗначениеДочернегоРеквизита = ПривестиЗначениеКТипуИзXML(лЗначениеДочернегоXML, лТипДанных);

					КонецЦикла; 
				КонецЦикла; 
			КонецЦикла; 

	КонецЦикла;
Показать
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот