XML -> Структура/Соответствие (хмл в структуру/соответствие)

mikaelangelm 70 1 1 3

- Преобразует XML файл (и даже простенькую html страничку) в виде строки или пути к файлу в Структуру (и подструктуры), содержащую Ключи = Узлам XML файла - Значения узлов одного уровня с одинаковыми наименованиями помещаются в массив - Аттрибуты игнорируются

Функция ЧитатьХМЛ(XML, КакСтруктуру = Ложь) Экспорт
	
	Если СтрНачинаетсяС(НРег(СокрЛП(Лев(XML, 1024))), "<") ИЛИ НРег(Лев(XML, 5)) = "<html" ИЛИ НРег(Лев(XML, 14)) = "<!doctype html" Тогда
		ЧтениеXML.УстановитьСтроку(XML);
	ИначеЕсли НайтиФайлы(Лев(СокрЛП(XML), 260)).Количество() > 0 Тогда 
		Файл = Новый Файл(XML);
		Если Не Файл.Существует() Тогда
			ВызватьИсключение "Файл """ + XML + """ не существует!";
		КонецЕсли;
		Файл = "";
		ЧтениеXML.ОткрытьФайл(XML);
	КонецЕсли;
	
	Если КакСтруктуру Тогда
    	Корень = ЧитатьКакСтруктуру(ЧтениеXML);
	Иначе
    	Корень = ЧитатьКакСоответствие(ЧтениеXML);
	КонецЕсли;
	
	ЧтениеXML = "";
	
	Возврат Корень;
КонецФункции

Функция ЧитатьКакСтруктуру(XML, ТипПоследнегоЭлемента = Неопределено)
	Ветка = Новый Структура;
	Значение = "";
	
	Пока XML.Прочитать() Цикл
		ТипУзла = XML.ТипУзла;
		Если ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
			ТипПоследнегоЭлемента = ТипУзлаXML.НачалоЭлемента;
			Временно = "";
			Если Ветка.Свойство(XML.Имя, Временно) Тогда
				Если ТипЗнч(Временно) <> Тип("Массив") Тогда
					ЭнЗэ = Новый Массив;
					ЭнЗэ.Добавить(Временно);
					Временно = ЭнЗэ;
					ЭнЗэ = "";
					Ветка.Удалить(XML.Имя);
					Ветка.Вставить(XML.Имя, Временно);
				КонецЕсли;
				Временно.Добавить(ЧитатьКакСтруктуру(XML, ТипПоследнегоЭлемента));
			Иначе
				Ветка.Вставить(XML.Имя, ЧитатьКакСтруктуру(XML, ТипПоследнегоЭлемента));
			КонецЕсли;
		ИначеЕсли ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
			ТипПоследнегоЭлемента = ТипУзлаXML.КонецЭлемента;
			Возврат ?(ЗначениеЗаполнено(Ветка), Ветка, Значение);
		ИначеЕсли ТипУзла = ТипУзлаXML.Текст И Не ТипПоследнегоЭлемента = ТипУзлаXML.Текст Тогда
			ТипПоследнегоЭлемента = ТипУзлаXML.Текст;
			Значение = XML.Значение;
			XML.Прочитать(); //Вычитка закрывающего тега
			Возврат Значение;
		Иначе
			// игнорируем текст вне узлов
			// можем также добавлять текст вне узлов в текст, находящийся в предыдущем узле через какой нибудь спецсимвол
			// например через Таб, код ниже:
			//Временно[Временно.ВГраница()] = Временно[Временно.ВГраница()] + Символы.Таб + XML.Значение
		КонецЕсли;
	КонецЦикла;
	
	Возврат Ветка;
КонецФункции

Функция ЧитатьКакСоответствие(XML, ТипПоследнегоЭлемента = Неопределено)	
	Ветка = Новый Соответствие;
	Значение = "";
	
	Пока XML.Прочитать() Цикл
		ТипУзла = XML.ТипУзла;
		Если ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
			ТипПоследнегоЭлемента = ТипУзлаXML.НачалоЭлемента; 
			Имя = XML.Имя;
			Временно = Ветка.Получить(Имя);
			Если Временно = Неопределено Тогда
				Ветка.Вставить(Имя, ЧитатьКакСоответствие(XML, ТипПоследнегоЭлемента));
			Иначе
				Если ТипЗнч(Временно) <> Тип("Массив") Тогда
					ЭнЗэ = Новый Массив;
					ЭнЗэ.Добавить(Временно);
					Временно = ЭнЗэ;
					ЭнЗэ = "";
					Ветка.Удалить(Имя);
					Ветка.Вставить(Имя, Временно);
				КонецЕсли;
				Временно.Добавить(ЧитатьКакСоответствие(XML, ТипПоследнегоЭлемента));
			КонецЕсли;
		ИначеЕсли ТипУзла = ТипУзлаXML.КонецЭлемента Тогда
			ТипПоследнегоЭлемента = ТипУзлаXML.КонецЭлемента;
			Возврат ?(ЗначениеЗаполнено(Ветка), Ветка, Значение);
		ИначеЕсли ТипУзла = ТипУзлаXML.Текст И Не ТипПоследнегоЭлемента = ТипУзлаXML.Текст Тогда
			ТипПоследнегоЭлемента = ТипУзлаXML.Текст;
			Значение = Значение + XML.Значение;
			XML.Прочитать(); //Вычитка закрывающего тега
			Возврат Значение;
		Иначе
			// игнорируем текст вне узлов
			// можем также добавлять текст вне узлов в текст, находящийся в предыдущем узле через какой нибудь спецсимвол
			// например через Таб, код ниже:
			//Временно[Временно.ВГраница()] = Временно[Временно.ВГраница()] + Символы.Таб + XML.Значение   						
		КонецЕсли
	КонецЦикла;
	
	Возврат Ветка;
КонецФункции
0
{10} Переменной Файл присвоено значение, но оно нигде не используется
{20} Переменной ЧтениеXML присвоено значение, но оно нигде не используется
Орфографическая ошибка в doctype: doctype
Орфографическая ошибка в Неопределено (найдено 3): Неопределено
Орфографическая ошибка в нибудь (найдено 2): нибудь

См. также

Перенести коллекцию КлючИЗначение

ДанныеXDTOИзДанныхИБ (БСП)

СтруктураОбъектаXDTOВДанныеИБ (БСП)

ФиксированныеДанные (БСП)

ОбъектXDTOИзДанныхXDTO (БСП)

СкопироватьРекурсивно (БСП)

АдресПоИдентификатору (БСП)

Проверка, есть ли ключ у соответствия

Модератору