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

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

# Код реализации

```1c
Функция ЧитатьХМЛ(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.Значение
		КонецЕсли
	КонецЦикла;

	Возврат Ветка;
КонецФункции
```