Данный RSS парсер портирован на язык 1С из PHP.
Исходным кодом RSS парсера послужил
"Project: MagpieRSS: a simple RSS integration tool
File: rss_parse.inc - parse an RSS or Atom feed return as a simple object."
author Kellan Elliott-McCrea
version 0.7a
license GPL
The lastest version of MagpieRSS can be obtained from:
http://magpierss.sourceforge.net
Не знаю как обстоят дела с копирайтом при переписывании алгоритма на другой язык (думаю никак), но на всякий случай будте осторожны при использовании в коммерческих реализациях.
Библиотека функций парсера помещена во внешнюю обработку в модуль объекта.
Проверить работу парсера теперь можно прямо из обработки (обновлена)
Как использовать:
Скопируйте функции из обработку в конфигурация в общий модуль (или куда вам нравиться).
Файл xml необходимо предварительно скачать на локальный (сетевой диск) например такой функцией:
Функция ЗапроситьФайлыССервера(СерверИсточник, СтрПарам, ИмяВходящегоФайла, ИспользоватьПрокси=ложь, ПроксиАдрес = "", ПроксиПользователь= "", ПроксиПароль = "", ПроксиПорт="") экспорт
Попыток = 10;
~Проба:если Не ИспользоватьПрокси тогда
HTTP = Новый HTTPСоединение(СерверИсточник);
иначе
ПроксиСервер = новый ИнтернетПрокси();
ПроксиСервер.Пользователь = ПроксиПользователь;
ПроксиСервер.Пароль = ПроксиПароль;
ПроксиСервер.Установить("http",ПроксиАдрес,ПроксиПорт);
HTTP = новый HTTPСоединение(СерверИсточник,,,,ПроксиСервер);
конецесли;
Попытка
HTTP.Получить("", ИмяВходящегоФайла);
возврат истина;
Исключение
ДСообщить(ОписаниеОшибки());
если Попыток>0 тогда
Попыток = Попыток-1;
перейти ~Проба;
конецесли;
Если ТипЗнч(HTTP) <> Тип("HTTPСоединение") тогда
Сообщить(НСтр("ru = 'Соединение с сервером не установлено'; en = 'Conection with server not established'; ge = 'Conection with server not established'"));
возврат неопределено;
конецесли;
КонецПопытки;
возврат истина;
КонецФункции
После того как файл скачен его можно парсить.
Для этого воспользуйтей оригинальной функцией:
MagpieRSS(ИмяФайлаXML), где в качестве параметра передается имя файл с полным путем.
Но данная функция возвращает не очень удобный объект для работы.
Поэтому рекомендую воспользоваться моей функцией, которая сама вызовет MagpieRSS, а возвращенный объект преобразует в таблицуЗначений.
ПолучитьТаблицуНовостей(СоответствиеПолей, ФайлRSS)
Второй параметр, файл XML с полным именем (включающим путь), а первый - соответствие, где:
Ключ: ТипТэга[ChannelTag/NewsTag] + "_" + ПолеИсточника
Значение: Структура(DBField:ПолеНовостиБД, Date:Признак необходимости конвертирования в дату)
Смысл соответствия в том, что в него вы помещаете все поля (тэги), которые вам надо получить из канала иновостей. Тэги бывают общие для канала и тогда перед именем ставим "ChannelTag_" и новостные и тогда перед именем ставим "NewsTag_".
Структура содержит два элемента.
Первый - строка - название колонки, куда будет помещаться контент из тэга ключа
если для разных тэгов источника указана одинаковая колонка, то информация суммируется через пробел (кроме тэгов даты).
Второй - булево - признак, что данная колонка таблицы является датой формата 1С инадо исходные данные парсить в дату.
Отдельным вопросом стоит определение исходных названий тэгов для источника, так как сздесь наблюдается отсутствие четкой практики.
Получить список тэгов канала можно моей следующей функцией:
Процедура FillSourceTags()
HTMLtext = "";
ТекURL = СтрЗаменить(URL, "http://", "");
ЗапроситьФайлыССервера(ТекURL,"", КаталогВременныхФайлов()+"rss.tmp");
rss = RSSParser.MagpieRSS(КаталогВременныхФайлов()+"rss.tmp");
ComplianceTags = новый ТаблицаЗначений;
ComplianceTags.Колонки.Добавить("TagType");
ComplianceTags.Колонки.Добавить("SourceTag");
ComplianceTags.Колонки.Добавить("ContentExample");
Индекс=0;
ТэгиКанала = новый ТаблицаЗначений;
ТэгиКанала.Колонки.Добавить("Tag");
ТэгиКанала.Колонки.Добавить("Content_Example");
Для каждого item из rss.channel цикл
ПолучитьТэгиРекурсивно(item, ТэгиКанала);
КонецЦикла;
ТэгиНовости = новый ТаблицаЗначений;
ТэгиНовости.Колонки.Добавить("Tag");
ТэгиНовости.Колонки.Добавить("Content_Example");
Для каждого item из rss.items цикл
ПолучитьТэгиРекурсивно(item, ТэгиНовости);
КонецЦикла;
ComplianceTags.Очистить();
Для каждого Эл из ТэгиКанала цикл
НовСтр = ComplianceTags.Добавить();
НовСтр.TagType = "ChannelTag";
НовСтр.SourceTag = Эл.Tag;
НовСтр.ContentExample = Эл.Content_Example;
КонецЦикла;
Для каждого Эл из ТэгиНовости цикл
НовСтр = ComplianceTags.Добавить();
НовСтр.TagType = "NewsTag";
НовСтр.SourceTag = Эл.Tag;
НовСтр.ContentExample = Эл.Content_Example;
КонецЦикла;
возврат ComplianceTags;
КонецПроцедуры
Функция ПолучитьТэгиРекурсивно(Элемент, МассивТэгов)
если ТипЗнч(Элемент) = Тип("Соответствие") или ТипЗнч(Элемент) = Тип("Массив") тогда
Для каждого Эл из Элемент цикл
ПолучитьТэгиРекурсивно(Эл, МассивТэгов);
КонецЦикла;
возврат неопределено;
иначеесли ТипЗнч(Элемент) = Тип("КлючИЗначение") тогда
Знч = ПолучитьТэгиРекурсивно(Элемент.Значение,МассивТэгов);
если Знч<>неопределено и МассивТэгов.Найти(Элемент.Ключ,"Tag")=неопределено тогда
НовСтр = МассивТэгов.Добавить();
НовСтр.Tag = Элемент.Ключ;
НовСтр.Content_Example = Знч;
конецесли;
возврат неопределено;
иначе
возврат Элемент;
конецесли;
КонецФункции
Функцию Преобразования строки в дату (используется в функции ПолучитьТаблицуНовостей) брать здесь //infostart.ru/public/70017/
Определить новая ли это новость или та которая уже существует в базе можно при помощи хэширования некоторых полей новости. Иногда каналы передают id новости иногда нет. Для хэширования я использую хэш функцию, которую можно взять здесь
Для компактного хранения результатов хэш функции можно переводить результат в строку такой функцией.
Работа парсера еще не достаточно протестирована поэтому если обнаружите ошибки вработе, напишите пожалуйстасюда или на мой Email(kosilov_DOG_inbox.ru).