Ошибка в структуре xml файла
В общем пытаюсь обработать ошибку XmlException, которая возникает тогда, когда xml-файл содержит ошибки в структуре или вообще ничего не содержит. К примеру, ошибка XmlException появляется и тогда, когда файл, который пытается загрузить пользователь, пуст, т.е. как минимум не содержит ни одного узла, а как максимум вообще может ничего не содержать. Но обработать таким образом ошибку не получается, как правильно ее обработать?
Но обработать таким образом ошибку не получается, как правильно ее обработать? так а какие проблемы то?
"как правильно ее обработать?" Из вопроса не понятно какое поведение от кода вы хотите добиться. Количество возможных вариантов неправильной структуры XML можно создавать до бесконечности. Но в своей сути структура может быть правильной или неправильной. Таким образом, если было выброшено исключение System.Xml.XmlException значит структура XML не корректная.
У вам в примере docXML.Load(userPath); находиться в не блока try . Это правильно? Файл парситься имено в этот момент.
Так поместите docXML.Load(userPath); в нуторь try < >и тогда будете перехватывать ошибки в catch (System.Xml.XmlException e) < >.
Работа с файлами отчетов Росстата¶
Файлы отчетов Росстата формируются в одну строку, что создает определенные сложности при просмотре в обычных тектовых редакторах.
В отличии, например, от файлов отчетов ФНС.
С файлами Росстата лучше работать с помощью программы XMLPad.
XMLPad имеет несколько режимов отображения:
- Стандартный режим (Source) отображения и редактирования кода.
В левой панели отображается структура XML-файла. Значения элементов можно отреактировать напрямую, либо через левую нижнюю панель.
XML ( англ. eXtensible Markup Language) — расширяемый язык разметки, предназначенный для хранения и передачи данных.
Простейший XML-документ выглядит следующим образом:
Первая строка — это XML декларация. Здесь определяется версия XML (1.0) и кодировка файла. На следующей строке описывается корневой элемент документа
Документ XML состоит из элементов (elements). Элемент начинается открывающим тегом (start-tag) в угловых скобках, затем идет содержимое (content) элемента, после него записывается закрывающий тег (end-teg) в угловых скобках.
Элементы могут содержать атрибуты, так, например, открывающий тег имеет атрибут lang , который принимает значение en . Значения атрибутов заключаются в кавычки (двойные или ординарные).
Некоторые элементы, не содержащие значений, допустимо записывать без закрывающего тега. В таком случае символ / ставится в конце открывающего тега:
Суть проблемы¶
Согласно приказу ФНС от 29 октября 2014 г. N ММВ-7-3/558@ в Книге продаж элемент (Сведения о покупателе, его ИНН/КПП) является необязательным, другими словами он может полностью отсутствовать.
Отрывок книги продаж выглядит следующим образом:
А нижеприведенный блок в Книге продаж необязателен:
Если есть сделки с иностранными контрагентами, у которых нет ИНН/КПП, следовательно, сведения о покупателе не заполняются. Но из-за логической ошибки в программе бухгалтерского учета, выгрузка сформированного отчета была невозможна, так как программа ошибочно требовала указать ИНН/КПП для всех контрагентов.
Чтобы обойти эту ошибку пришлось вместо ИНН указать регистрационный номер контрагента в стране регистрации, а вместо КПП указать девять нулей.
Но при попытке отравить выгруженный отчет в контролирующий орган, возникала обратная ошибка. Так как ИНН и КПП были фиктивными, то при проверке отчета не выполнялись контрольные соотношения.
Проверка файла отчета программой Tester
ИНН и КПП это не произвольный набор чисел, они содержат определенные контрольные соотношения.
А как проверить, что значение, хранилища значения, повреждено?
С этим есть некоторые сложности, так как что при получении значения из поврежденного хранилища значений мы получаем "Неопределено", ровно тоже самое, если в хранилище значения, было помещено "Неопределено". В некоторых случаях, при получении значения возникают исключение, но не всегда. В итоге получилась такая проверка:
Получилась (почти) универсальная обработка, по поиску и исправлению поврежденных данных хранилища значения. В настоящий момент, обработка поддерживает следующие типы объектов:
- Справочники (реквизиты, табличные части)
- Документы (реквизиты, табличные части)
- Регистры сведений (ресурсы, реквизиты)*
- Регистры накопления (ресурсы, реквизиты)*
- Планы видов характеристик (реквизиты, табличные части)
* - В измерениях регистра, не может быть реквизитов типа "ХранилищеЗначения"
Обратите внимание, обработка записывает в поврежденное хранилище значения, значение "Неопределено", некоторые объекты не ожидают такого рода данных и могут выдавать ошибки при открытии и пр. При желании, вы можете сами доработать обработку, чтобы в зависимости от объекта, у вас вставлялась ожидаемая объектом структура и пр. Так же обработка предоставляется "AS IS", так что делайте бэкапы, перед выполнением. Обработка может иметь ошибки, в случае нахождения оных - пишите.
Обработка разрабатывалась и тестировалась на платформе 8.3.10.2505 с конфигурацией 1С:Розница 2.2.5. Но обработка должна быть совместима с любыми конфигурациями на управляемых формах.
1 ответ 1
Чтобы проверить пустой ли файл, как вариант, можно попробовать отрыть файл с XML как обычный текстовый и проверить длину содержимого.
Что касается структуры XML, то здесь только валидация по схеме (xsd). Пример здесь.
на самом деле думала над тем, чтобы проверить файл на количество символов внутри него, но отказалась от этой мысли, т.к. файл может быть пуст, может что-то содержать, к примеру, какой-то левый текст. В общем целом, насколько я поняла, когда нарушена структура xml - файла выкидывается ошибка XmlException, а в чем конкретно проблема, неважно: будь то файл пустой, или что-то сдержит. спасибо за ссылку, посмотрю, попробую, если это правильный ответ, отмечу!
Это плохой способ, имхо. Что если попадётся большой файл в сотни мегабайт? Он весь считается в память только лишь для проверки на пустоту. Потом повторно будет читаться для парсинга xml.
В данной главе приведены некоторые практические приемы работы с XML-файлами.
Поиск информации в XML файлах (XPath)¶
XPath ( англ. XML Path Language) — язык запросов к элементам XML-документа. XPath расширяет возможности работы с XML.
XML имеет древовидную структуру. В документе всегда имеется корневой элемент (инструкция к дереву отношения не имеет). У элемента дерева всегда существуют потомки и предки, кроме корневого элемента, у которого предков нет, а также тупиковых элементов (листьев дерева), у которых нет потомков. Каждый элемент дерева находится на определенном уровне вложенности (далее — «уровень»). У элементов на одном уровне бывают предыдущие и следующие элементы.
Это очень похоже на организацию каталогов в файловой системе, и строки XPath, фактически, — пути к «файлам» — элементам. Рассмотрим пример списка книг:
XPath запрос /bookstore/book/price вернет следующий результат:
Сокращенная форма этого запроса выглядит так: //price .
С помощью XPath запросов можно искать информацию по атрибутам. Например, можно найти информацию о книге на итальянском языке: //title[@lang="it"] вернет
Чтобы получить больше информации, необходимо модифицировать запрос //book[title[@lang="it"]] вернет:
В приведенной ниже таблице представлены некоторые выражения XPath и результат их работы:
Выражение XPath | Результат |
---|---|
/bookstore/book[1] | Выбирает первый элемент book , который является потомком элемента bookstore |
/bookstore/book[position() | Выбирает первые два элемента book , которые являются потомками элемента bookstore |
//title[@lang] | Выбирает все элементы title с атрибутом lang |
//title[@lang=’en’] | Выбирает все элементы title с атрибутом lang , который имеет значение en |
/bookstore/book[price>35.00] | Выбирает все элементы book , которые являются потомками элемента bookstore и которые содержать элемент price со значением больше 35.00 |
/bookstore/book[price>35.00]/title | Выбирает все элементы title элементов book элементов bookstore , которые содержать элемент price со значением больше 35.00 |
Синтаксическая Проверка Вашего XML
Чтобы проверить XML синтаксис, воспользуйтесь XML валидатором.
Вставьте ваш XML код в текстовую область ниже, и проверьте синтаксис, кликнув кнопку “Проверить”.
Замечание: Валидатор проверяет только то, что ваш XML является “Правильно сформированным”. Если вы хотите осуществить проверку XML файл на соответствие DTD, смотрите последний параграф статьи.
Для начала, давайте рассмотрим варианты причин, которые могли привести к данной проблеме:
- Наш любимый кеш, хоть в данном случае редко он виновник, но с него стоит начать в решении проблемы;
- Не совпадающие метаданные (Например центральная база была обновлена, а изменения не доехали и/или узел считает что он уже обновлен, тут как раз часто помогает очистка кеша и повторный обмен);
- И наконец проблема, которой и посвящена данная публикация - повреждение значений реквизитов, у которых тип "Хранилище значения". Данная проблема чаще всего возникает при резком отключении компьютера во время записи объектов и прочих случаях (предположительно, хранилище значения, хранится отдельно и записывается в базу, после записи основного объекта, в основном, эти проблемы возникают в файловых базах).
XSD схема¶
XML Schema — язык описания структуры XML-документа, его также называют XSD. Как большинство языков описания XML, XML Schema была задумана для определения правил, которым должен подчиняться документ. Но, в отличие от других языков, XML Schema была разработана так, чтобы её можно было использовать в создании программного обеспечения для обработки документов XML.
После проверки документа на соответствие XML Schema читающая программа может создать модель данных документа, которая включает:
- словарь (названия элементов и атрибутов);
- модель содержания (отношения между элементами и атрибутами и их структура);
- типы данных.
Каждый элемент в этой модели ассоциируется с определённым типом данных, позволяя строить в памяти объект, соответствующий структуре XML-документа. Языкам объектно-ориентированного программирования гораздо легче иметь дело с таким объектом, чем с текстовым файлом.
XML Ошибки
Ошибки в XML документах остановят выполнение ваших XML приложений.
W3C спецификация XML провозглашает, что программа должна прекратить обработку XML документа, если она найдет ошибку. Причина в том, что XML-ориентированное программное обеспечение должно быть небольшим, быстрым и совместимым.
HTML браузеры будут отображать документы с ошибками (наподобие пропусков конечных тегов). HTML браузеры являются большими (тяжеловесными) и несовместимыми, поскольку они имеют значительную часть ненужного кода для обращения с (и отображения) HTML ошибок.
В XML ошибки не разрешены.
Сущности¶
Некоторые символы в XML имеют особые значения и являются служебными. Если вы поместите, например, символ < внутри XML элемента, то будет сгенерирована ошибка, так как парсер интерпретирует его, как начало нового элемента.
В примере ниже будет сгенерирована ошибка, так как в значении "ООО" атрибута НаимОрг содержатся символы < и >.
Также ошибка будет сгенерирована и в слудющем примере, если название организации взять в обычные кавычки (английские двойные):
Сущность | Символ | Значение |
---|---|---|
< | меньше, чем | |
> | > | больше, чем |
& | & | амперсанд |
' | ' | апостроф |
" | " | кавычки |
Только символы < и & строго запрещены в XML. Символ >допустим, но лучше его всегда заменять на сущность.
Таким образом, корректными будут следующие формы записей:
В последнем примере английские двойные кавычки заменены на французские кавычки («ёлочки»), которые не являются служебными символами.
Решение проблемы¶
Так как файл содержал свыше 15000 строк и большое количество сделок, надо было автоматизировать данный процесс.
С помощью запроса Xpath и сервиса Xpath-Tester были найдены все сделки с иностранными контрагентами. Запрос имел вид //СвПокуп[СведЮЛ[@КПП0"000000000"]] . Получилось приличное количество сделок, свыше 200.
Надо было удалить порядка 700 строк, полностью содержащих блоки (причем с разными псевдо-ИНН):
Большинство программ умеет искать и заменять максимум одну строку на другую. В данном случае надо было искать и заменять блок текста из трех строк.
С этим успешно справилась программа UVFilesCorrector. Интерфейс программы прост до невозможности. В нижней части на вкладке Файлы выбираем нужный нам файл.
В верхнем поле Список замен необходимо нажать на пустое поле и создаем правило для замены. В данном случае оно выглядело так:
На скриншоте видно не все выражение, в поле Что найти: в режиме Шаблон (регулярное выражение) введено:
Десять точек в ИННЮЛ=". " являются регулярным выражением и означают, что на их месте может стоять любой символ. В итоге получилось, что под замену попадали все блоки, имеющие нулевые КПП. Комбинация символов \r\n также является регулярным выражением и означает перенос строки.
Всего у организации было 14 контрагентов, с которыми в общей сумме было заключено 266 сделок. Следовательно, после нажатия на кнопку Заменить получилось 266 замены.
Буквально за один простой шаг по заданному условию было удалено свыше 700 строк. Проверка Tester’ом ошибок не выявила и файл был успешно отправлен в контролирующий орган.
Как работает обработка?
Кодировки¶
И еще один важный момент, который стоит рассмотреть — кодировки. Существует множество кодировок, о них подробнее можно прочитать в статье Набор символов.
Самыми распространенными кириллическими кодировками являются Windows-1251 и UTF-8 . Последняя является одним из стандартов, но большая часть ФНС отчетности имеет кодировку Windows-1251 .
В XML файле кодировка объявляется в декларации:
Часто можно столкнуться с ситуацией, когда текстовый редаткор некорректно распознает кодировку и отображает кракозябры. В такой случае, необходимо выбрать кодировку вручную, для этого выполните:
Программа | Кодировка |
---|---|
Notepad++ | «Документ → Кодировка» |
Geany | «Документ → Установить кодировку» |
Firefox | «Вид → Кодировка» |
Chrome | «Настройка → Дополнительные инструменты → Кодировка» |
В большинстве случаев при работе с русскоязычными файлами помогает переключение кодировки на Windows-1251 или UTF-8 . Если все равно не удается прочитать содержимое XML документа, стоит открыть его в Mozilla Firefox, он отлично распознает кодировки.
Если ничего не помогает, вполне возможно, что файл был поврежден.
Валидные (Проверенные) XML Документы
“Валидный” XML документ – это “Правильно Сформированный” XML документ, который также подчиняется правилам Определения Типа Документа (от англ. – Document Type Definition или DTD):
Не забудь мне позвонить завтра! |
Объявление DOCTYPE в примере выше является ссылкой на внешний файл DTD. Содержимое этого файла показано в параграфе ниже.
XML Схема
W3C поддерживает основанную на XML альтернативу DTD, называемую XML Схемой:
Вы можете подробнее ознакомиться с XML Схемой на сайте в статье, посвященной данной теме.
Правильно Сформированные XML Документы
“Правильно Сформированный” XML документ имеет корректный XML синтаксис.
Синтаксические правила были описаны в статье про создание xml:
Структура XML¶
XML документ должен содержать корневой элемент. Этот элемент является «родительским» для всех других элементов.
Все элементы в XML документе формируют иерархическое дерево. Это дерево начинается с корневого элемента и разветвляется на более низкие уровни элементов.
Все элементы могут иметь подэлементы (дочерние элементы):
XML DTD
Назначение DTD – определить структуру XML документа. Оно определяет структуру со списком допустимых элементов:
Если вы хотите более подробно ознакомиться с DTD, вы найдете соответствующую статью на сайте.
Правила синтаксиса (Валидность)¶
Структура XML документа должна соответствовать определенным правилам. XML документ отвечающий этим правилам называется валидным (англ. Valid — правильный) или синтаксически верным. Соответственно, если документ не отвечает правилам, он является невалидным .
Основные правила синтаксиса XML:
- Теги XML регистрозависимы — теги XML являются регистрозависимыми. Так, тег не то же самое, что тег .
Открывающий и закрывающий теги должны определяться в одном регистре:
- XML элементы должны соблюдать корректную вложенность:
- У XML документа должен быть корневой элемент — XML документ должен содержать один элемент, который будет родительским для всех других элементов. Он называется корневым элементом.
- Значения XML атрибутов должны заключаться в кавычки:
Удаление лишних блоков(абзацев) из XML по заданному условию¶
Теги в структуре XML образуют многострочные блоки. Иногда возникает необходимость удалить ряд целых блоков по заданному условию. В качестве примера будет рассмотрена ситуация с отчетом по НДС .
Из-за несовершенства некоторых программ, периодически возникают проблемы при передаче файлов в контролирующие органы.
XML Валидатор
Чтобы проверить синтаксис ваших XML файлов, можете воспользоваться XML валидатором (смотрите ниже).
Синтаксическая Проверка XML Файла
Вы можете сделать синтаксическую проверку XML файла, напечатав URL файла в поле ввода ниже, и затем кликнув кнопку “Проверить”:
Замечание: Если вы получаете ошибку “Доступ запрещен”, значит настройки безопасности вашего браузера не позволяют доступ к файлам через домены.
Как же решить проблему в пункте №3?
Варианты решения три (от худшего к лучшему):
Исправление невалидных XML-файлов¶
Исправляется данная проблема просто — данные символы необходимо заменить на их сущности (подробнее смотрите раздел Сущности ). Сделать это можно, воспользовавшись любым нормальным текстовым редактором с функцией поиска и замены с использованием регулярных выражений.
Также можно воспользоваться скриптом xml_healer.py , который автоматически заменяет управляющие символы на их сущности и удаляет лишние символы после закрывающего родительского тега. Подробная инструкция по работе со скриптом приведена в главе IV. Скрипт для замены служебных символов в XML .
Проверка Вашего XML На Соответствие DTD
Если вы знаете DTD, и у вас запущен Internet Explorer, вы можете проверить ваш XML в текстовой области ниже.
Просто добавьте объявление DOCTYPE к вашему XML и кликните кнопку “Проверить”:
Читайте также: