![]() |
|
Прочитать описания элементов из XSD-схемы с указанием полного пути к каждому элементу. | ☑ | ||
---|---|---|---|---|
0
SleepyHead
гуру
13.07.20
✎
07:38
|
Частно приходится сталкиваться с задачей сравнения регламентированных отчетов (НДС, ЕНВД, Налог на прибыль, РСВ, СЗВ-М и так далее).
Две подзадачи 1. Понять, чем отличается корректировка отчета от первичного 2. Отчет подготовлен в 1С, выгружен, подгружен в СБИС-контур, далее могли быть внесены изменения и отправлены. Понять, чем отличается версия в СБИС от версии 1с. Сделал внешний отчет, в котором XML-файлы разбираются рекурсивно, отчеты сравниваются, все красиво. Чтобы отчет выглядел читабельно для пользователя, идентификаторы элементов узлов нужно представить в читаемом виде. Пока что реализовал это прямо в обработке, в макете, сопоставляю полное имя элемента и его текстовой представление, пример: Файл\Документ\НомКорр - номер корректировки Файл\Документ\ВерсФорм - версия формата и так далее. Описания форматов опубликованы, их легко найти в том же консультанте. Однако, создавать макет сопоставления для каждого вида отчета - как-то скучновато, да и версии форматов периодически меняются. Что хочу: 1. Взять XSD-схему с описанием формата файла отчетности 2. Разобрать ее и вытянуть описания всех элементов, как описано выше. Что получилось: нашел тему на инфостарте, где приведен пример чтения XSD-схемы (http://catalog.mista.ru/public/311011/) Однако, там разбираются способы чтения самого XML-файла при помощи схемы. а у меня задача другая , получить описания элементов и не более того. Текст схемы на примере отчета по прибыли я нашел на сайте налоговой, загнал ее в текстовый макет, и прочитал эту схему. А что дальше с ней делать, пока не понял. Посмотрел полученную схему в отладчике, не понял, с чего начать ее рекурсивный разбор, чтобы выйти на описания элементов (Файл\Документ\НомКорр например) Обращаюсь к ием, кто со схемами работал. Макет = ПолучитьМакет("Схема_PRIB_05_08"); ЧтениеСхемы = Новый ЧтениеXML; ЧтениеСхемы.УстановитьСтроку(Макет.ПолучитьТекст()); ПостроительДОМ = Новый ПостроительDOM; ДокументДом = ПостроительДОМ.Прочитать(ЧтениеСхемы); ПостроительСхем = Новый ПостроительСхемXML; Схема = ПостроительСхем.СоздатьСхемуXML(ДокументДом); |
|||
1
quest
13.07.20
✎
08:58
|
ФабрикаXDTO имеет все что тебе надо - пакеты, описания и т.д. Читай схему в Фабрику и работай с типами как тебе надо.
|
|||
2
SleepyHead
гуру
13.07.20
✎
10:15
|
(1) Спасибо, вот только в самом регл. отчете схема не указана. Но в этом направлении подумаю.
|
|||
3
quest
13.07.20
✎
11:19
|
а как тогда отчет собирается? руками пишутся элементы?
|
|||
4
SleepyHead
гуру
13.07.20
✎
14:15
|
(3) Наименования атрибутов и блоков вписал в макет внешнего отчета, например:
Файл\Документ\НомКорр -> Номер корректировки. В отчете видно "Номер корректировки". Если не впишу в макет, то отчет тоже сформируется, но с идентификаторами элементов из самого XML-файла: "Файл\Документ\НомКорр". |
|||
5
SleepyHead
гуру
13.07.20
✎
15:42
|
(1) Фабрику создал, пакеты вижу, но как извлечь оттуда описания элементов - не понимаю, хоть тресни :((
Посмотрел саму схему. Очень похоже на обычный XML-файл, и структура в общем понятная. Если разобрать его рекурсивно, то можно выделить идентификаторы элементов из тегов xs:element, а описания из вложенного теша xs:annotation \ xs:documentation Но изобретать велосипед не хочется. Может быть , есть примеры разбора пакетов фабрики? На инфостарте не нашел пока. |
|||
6
quest
13.07.20
✎
16:48
|
лучше изобрети. сам разберешься и на инфостарте потом опубликуешь
|
|||
7
SleepyHead
гуру
13.07.20
✎
17:06
|
(6) Разобрался, путем изобретения небольшого велосипеда под решение моей конкретной маленькой задачи.
Насчет публикации на инфостарте - сомневаюсь, что это будет кому-то интересно, потому что задача очень специфическая. Там полно статей, которые решают проблему чтения/записи XML через схемы и фабрику, а мне нужно получить описания элементов, и не более того. Схема - этот тот же самый файл XML, который можно разбирать рекурсивно. Нужно анализировать только узлы "xs:element" и "xs:attribute", а внутри них собирать описания элементов. Тестовый код делал в форме обработки, получилось буквально несколько десятков строк. В итоге получил массив структур (потому что разбирал на клиенте) с полями "путь", "Наименование", где путь - это полный путь от корня XML-файла, а Наименование - это описание элемента или атрибута из схемы, вот результат, вытащенный отладчиком: "Файл\Документ" "Состав и структура документа" "Файл\Документ\СвНП" "Сведения о налогоплательщике" "Файл\Документ\СвНП\НПЮЛ" "Налогоплательщик - организация (обособленное подразделение)" "Файл\Документ\СвНП\НПЮЛ\СвРеоргЮЛ" "Сведения о реорганизованной (ликвидированной) организации (обособленном подразделении)" "Файл\Документ\СвНП\НПЮЛ\СвРеоргЮЛ\ФормРеорг" "Код формы реорганизации (ликвидации) / изменения полномочий (закрытия) обособленного подразделения" "Файл\Документ\СвНП\НПЮЛ\СвРеоргЮЛ\ИННЮЛ" "ИНН реорганизованной организации (обособленного подразделения) / изменившего полномочия (закрытого) обособленного подразделения" "Файл\Документ\СвНП\НПЮЛ\СвРеоргЮЛ\КПП" "КПП реорганизованной организации (обособленного подразделения) / изменившего полномочия (закрытого) обособленного подразделения" "Файл\Документ\СвНП\НПЮЛ\НаимОрг" "Наименование организации (обособленного подразделения)" "Файл\Документ\СвНП\НПЮЛ\ИННЮЛ" "ИНН организации" "Файл\Документ\СвНП\НПЮЛ\КПП" "КПП" "Файл\Документ\СвНП\Тлф" "Номер контактного телефона" "Файл\Документ\Подписант" "Лицо, подписавшее документ" "Файл\Документ\Подписант\ФИО" "Фамилия, имя, отчество" "Файл\Документ\Подписант\СвПред" "Сведения о представителе налогоплательщика, налогового агента" "Файл\Документ\Подписант\СвПред\НаимДок" "Наименование и реквизиты документа, подтверждающего полномочия представителя налогоплательщика, налогового агента" "Файл\Документ\Подписант\СвПред\НаимОрг" "Наименование организации - представителя налогоплательщика, налогового агента " "Файл\Документ\Подписант\ПрПодп" "Признак лица, подписавшего документ" "Файл\Документ\Прибыль" "Налоговая декларация по налогу на прибыль организаций" "Файл\Документ\Прибыль\НалПУ" "Сумма налога, подлежащая уплате в бюджет, по данным налогоплательщика (налогового агента)" "Файл\Документ\Прибыль\НалПУ\НалПУАв" "Сумма налога, подлежащая уплате в бюджет, по данным налогоплательщика (налогового агента) - для организаций, уплачивающих авансовые платежи и налог на прибыль организаций" и так далее. А вот код: &НаКлиенте Процедура Тест(Команда) СтрокаСхемы = ПолучитьТекстИзМакета("Макет"); ЧтениеСхемы = Новый ЧтениеXML; ЧтениеСхемы.УстановитьСтроку(СтрокаСхемы); ПостроительДОМ = Новый ПостроительDOM; ДокументДом = ПостроительДОМ.Прочитать(ЧтениеСхемы); МассивОписаний = Новый Массив; РазобратьРекурсивно(ДокументДом.ЭлементДокумента, "", МассивОписаний); КонецПроцедуры &НаКлиенте Процедура РазобратьРекурсивно(УзелРодитель, Знач ПолныйПуть, МассивОписаний) Перем Узел, УзелДокументации, Имя, Представление, ТекущийПолныйПуть, ЭтоАтрибут; Если ВРег(УзелРодитель.ИмяЭлемента)=ВРег("xs:element") ИЛИ ВРег(УзелРодитель.ИмяЭлемента)=ВРег("xs:attribute") Тогда Имя = ПолучитьЗначениеАтрибута(УзелРодитель, "name"); ТекущийПолныйПуть = ПолныйПуть + ?(ЗначениеЗаполнено(ПолныйПуть), "\", "") + Имя; ЭтоАтрибут = ВРег(УзелРодитель.ИмяЭлемента)=ВРег("xs:attribute"); Иначе Имя = ""; ТекущийПолныйПуть = ПолныйПуть; ЭтоАтрибут = Ложь; КонецЕсли; Для Каждого Узел из УзелРодитель.ДочерниеУзлы Цикл Если ВРег(Узел.ИмяЭлемента)=ВРег("xs:annotation") Тогда Если ЗначениеЗаполнено(ТекущийПолныйПуть) И Найти(ТекущийПолныйПуть, "\")>0 Тогда Представление = ""; Для Каждого УзелДокументации из Узел.ДочерниеУзлы Цикл Если ЗначениеЗаполнено(Имя) И УзелДокументации.ТипУзла=ТипУзлаDOM.Элемент И ВРег(УзелДокументации.ИмяЭлемента)=ВРег("xs:documentation") Тогда Представление = Представление + ?(ЗначениеЗаполнено(Представление), Символы.ПС, "") + УзелДокументации.ТекстовоеСодержимое; КонецЕсли; КонецЦикла; МассивОписаний.Добавить(Новый Структура("Путь,Наименование", ТекущийПолныйПуть, Представление)); КонецЕсли; ИначеЕсли НЕ ЭтоАтрибут Тогда РазобратьРекурсивно(Узел, ТекущийПолныйПуть, МассивОписаний); КонецЕсли; КонецЦикла; КонецПроцедуры &НаКлиенте Функция ПолучитьЗначениеАтрибута(Узел, Знач ИмяАтрибута) ТекЭлемент = Узел.Атрибуты.ПолучитьИменованныйЭлемент(ИмяАтрибута); Возврат ?(ТекЭлемент=Неопределено, "", ТекЭлемент.Значение); КонецФункции &НаСервере Функция ПолучитьТекстИзМакета(Знач ИмяМакета) Возврат РеквизитФормыВЗначение("Объект").ПолучитьМакет(ИмяМакета).ПолучитьТекст(); КонецФункции |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |