Обработка ошибок при разборе xml

Содержание:

1.       XML – расширяемый язык разметки

2.       Устранение Ошибки разбора XML в 1С

3.       «Обход» Ошибки разбора XML в 1С   

1.    XML – расширяемый язык разметки

В данной статье речь пойдёт о причинах возникновения фатальной ошибки «Ошибка разбора XML» и способах устранения данной неполадки. Также будет дана инструкция не по устранению, но «обходу» ошибки, то есть действиям на опережение.

XML (с английского – extensible markup language – расширяемый язык разметки) – это язык разметки, который рекомендует Консорциум Всемирной паутины. Обычно язык разметки XML служит для описания документации, соответствующего типа, а также описывает действия соответствующих процессоров. Расширяемый язык разметки имеет довольно простой синтаксис, поэтому используется по всему миру, чтобы создавать и обрабатывать документацию программным способом. Он создавался именно для использования в Интернете. XML назвали именно расширяемым языком разметки, так как в нём нет фиксации разметки, которая содержится внутри документа, а именно: программист может создавать любую разметку, а ограничения будут встречаться лишь в синтаксисе.

2.    Устранение Ошибки разбора XML в 1С

«Ошибка разбора XML» возникает исключительно в тонком клиенте 1С. Также стоит отметить, что «Ошибка разбора XML» также довольна схожа с ошибкой по формату потока, которая возникает в толстом клиенте. Обычно в 1С «Ошибка разбора XML» возникает по причине наличия кэша метаданных. И если очистить кэш, то ошибка будет устранена. Выглядит окно с ошибкой, а также окно с комментариями от технической поддержки следующим образом:

Рис. 1 Окно Ошибки разбора XML в 1С

XML данные читаются по потокам, так что в каждый из моментов времени объект «сосредоточен» в некотором узле XML. Из-за этого также может возникать фатальная ошибка «Ошибка разбора XML». Для того чтобы её устранить, можно вызвать функцию «ИсключениеЧтенияXml», как показано на скриншоте примера ниже:

Рис. 2 Вызов функции ИсключениеЧтенияXML для устранения Ошибки разбора XML в 1С  

3.    «Обход» Ошибки разбора XML в 1С

Данные два способа (очистка кэша метаданных и функция «ИсключениеЧтенияXml») – не все возможные варианты устранения ошибки разбора XML. Далее рассмотрим нестандартный подход, который позволит избежать ошибки еще до её возникновения.

Для наглядности будем работать в конфигурации 1С:Бухгалтерия предприятия, одной из наиболее распространенных программ фирмы 1С. У многих людей, которые пользуются программой 1С:Отчётность появляются неполадки при попытках открыть данные/файлы от налоговой. Чтобы открыть такой файл повторяем следующие действия:

·        Переходим по пути: «Настройки 1С:Отчётности → Журнал обмена с контролирующими органами», как показано на скриншоте ниже:

Рис. 3 Настройка 1С Отчетности

·        Далее кликаем на «Запросы» и выделяем ту выписку, которую не было возможности открыть из-за ошибки, как продемонстрировано на скриншоте ниже:

Рис. 4 Выбор выписки с Ошибкой разбора XML в 1С

·        Обращаем внимание на стадию отправки, которая располагается внизу этого сообщения, и кликаем два раза на зелёный круг:

Рис. 5 Стадия отправки документа с Ошибкой разбора XML в 1С

·      Появляется транспортное сообщение, в нём кликаем на «Выгрузить» и выбираем папку, куда необходимо провести выгрузку, после чего сохраняем данный файл. Пробуем открыть его, при помощи любого из графических редакторов, который может поддерживать формат PDF, как показано на скриншоте ниже:

Рис. 6 Результат обхода Ошибки разбора XML в 1С

·        Всё успешно открылось, а ошибка даже не успела возникнуть.

Специалист компании «Кодерлайн»

Айдар Фархутдинов

This issue was originally filed by da…@altern.org


What steps will reproduce the problem?

  1. Parse an XML document that is not well-formed with DomParser.parseFromString
  2. Try to find out if there is an error and get an error message
    3.

What is the expected output? What do you see instead?
I expect an exception to be thrown, with the error message. Instead I get the same result as with Javascript: a DOM tree containing some error info as a return value. Not only does this make it hard to handle errors (what if I want to parse an error document ?), but the returned XML depends on the web browser. I would expect Dart to at least hide browser implementation differences and provide robust error handling.

What version of the product are you using? On what operating system?
Latest version. Ubuntu 12.04.

Please provide any additional information below.
See also: http://stackoverflow.com/q/11563554/438970

I have tried to use dart-xml as an alternative to DomParser, but it does not provide good support for XML comments and namespaces yet.

Надо обернуть всю логику по разбору XML в функцию, которая обработает исключения и запишет полную информацию об ошибках, например, в таблицу. Как-то так:

create table parseErrors (guid raw (16), errm varchar2 (4000), created timestamp);

create or replace function myXmlParser (docGuid raw, doc clob) return varchar2 is
    procedure saveParseError (guid raw, errm varchar2) is 
    pragma autonomous_transaction;
    begin 
        insert into parseErrors values (guid, errm, systimestamp);
        commit;
    end ;
begin
    -- **здесь необходимая логика, в которой может возникнуть ошибка**
    return xmlType (doc).getStringVal (); 
exception when others then 
    saveParseError (docGuid, sqlerrm||chr(10)||sys.dbms_utility.format_error_backtrace());
    return 'errorneous';
end myXmlParser;
/

Выборка для теста (вместо sys_guid() должна быть колонка с GUID из запроса):

select myXmlParser (sys_guid(), '<row>some data</row>') from dual union all
select myXmlParser (sys_guid(), '</row>illegal XML syntax</row>') from dual
;

выведет:

RESULT    
------------------------
<row>some data</row>   
errorneous     

Kакие были ошибки:

set lines 999
col errm for a40 wrapp
select * from parseErrors;

GUID                             ERRM                                     CREATED                     
-------------------------------- ---------------------------------------- -----------------------------
7106268B980F02D3E0530A01A8C04FBB ORA-31011: XML parsing failed            2018-07-15 12:32:41,204757000
                                 ORA-06512: at "SYS.XMLTYPE", line 272                                 
                                 ORA-06512: at "DB.MYXMLPARSER", line 10                               

PS В вопросе мало информации по локализации причины ошибки, но думаю ссылки на похожие топики тут и тут будут полезны.

Мне все еще комфортно работать с XML-файлами. Я просмотрел несколько примеров в Интернете и был поражен отсутствием обработки ошибок.

Самая частая ошибка — это что-то вроде el.Attributes["name"].Value. Поскольку XML редактируется человеком, возможно, что атрибут отсутствует. И попытка сослаться на свойство Value на null вызовет исключение. Другие проблемы могут быть связаны с данными, не имеющими ожидаемого формата.

Итак, я начал писать несколько вспомогательных методов расширения в следующих строках:

public static class XmlHelpers
{
    public static string GetValue(this XmlAttribute attr, string defaultValue = "")
    {
        if (attr != null)
            return attr.Value;
        return defaultValue;
    }

    public static bool GetValueBool(this XmlAttribute attr, bool defaultValue = false)
    {
        bool value;
        if (bool.TryParse(attr.GetValue(), out value))
            return value;
        return defaultValue;
    }
}

Я знаю, что это сработает. Но я что-нибудь упускаю? XmlDocument уже предоставляет функциональные возможности, делающие такие вещи ненужными? Мне просто интересно, как другие справляются с этим.

Я понимаю, что многие файлы XML никогда не редактируются людьми. И по этой причине многие люди могут просто написать код, предполагающий, что ошибок не будет. Если есть ошибка, значит, есть исключение. Я могу понять, что. Но я надеялся дать своему приложению немного больше гибкости, если файлы редактируются людьми и что-то отформатировано неправильно.

Мне все еще комфортно работать с файлами XML. Я смотрел несколько примеров в Интернете и был поражен отсутствием обработки ошибок.

Наиболее распространенная ошибка это что-то вроде el.Attributes["name"].Value, Поскольку XML доступен для редактирования человеком, возможно, этот атрибут отсутствует. И пытается сослаться на Value собственность на null поднимет исключение. Другие проблемы будут связаны с тем, что данные не находятся в ожидаемом формате.

Поэтому я начал писать некоторые вспомогательные методы расширения в соответствии со следующим:

public static class XmlHelpers
{
    public static string GetValue(this XmlAttribute attr, string defaultValue = "")
    {
        if (attr != null)
            return attr.Value;
        return defaultValue;
    }

    public static bool GetValueBool(this XmlAttribute attr, bool defaultValue = false)
    {
        bool value;
        if (bool.TryParse(attr.GetValue(), out value))
            return value;
        return defaultValue;
    }
}

Я знаю, что это сработает. Но я что-то упустил? Есть ли XmlDocument уже предоставляют функциональность, которая делает этот тип вещей ненужным? Мне просто интересно, как другие справляются с этим.

Я понимаю, что многие XML-файлы никогда не редактируются людьми. И по этой причине многие люди могут просто написать код, который предполагает, что ошибок не будет. Если есть ошибка, то есть исключение. Я могу понять, что. Но я надеялся придать своему приложению немного большей гибкости, если файлы редактируются людьми, а что-то не отформатировано совершенно правильно.

2013-06-30 18:03

2
ответа

Решение

В зависимости от того, какие ошибки вас интересуют (и как выглядит XML, который вы анализируете), класс XmlSerializer может быть полезен:

void Main()
{
    var xmlSerializer = new XmlSerializer(typeof(Foo));
    var foo1 = (Foo)xmlSerializer.Deserialize(new StringReader(@"<Foo a=""11""></Foo>"));
    Console.WriteLine(foo1.A); // 11

    var foo2 = (Foo)xmlSerializer.Deserialize(new StringReader(@"<Foo></Foo>"));
    Console.WriteLine(foo2.A); // 10 (fell back to the default)

    // throws format exception
    var foo3 = (Foo)xmlSerializer.Deserialize(new StringReader(@"<Foo a=""x""></Foo>"));
}

// Define other methods and classes here
[XmlRoot("Foo")]
public class Foo {
    public Foo() { this.A = 10; }

    [XmlAttribute("a")]
    public int A { get; set; }
}

Обработка ошибок разбора, очевидно, сложнее. Одним из способов может быть использование XmlSerializer, как описано выше, но использование строки для всех типов (возможно, со свойствами оболочки, которые включают обработку некорректного форматирования). Чтобы получить больше безопасности типов, вы можете определить пользовательские типы, которые реализуют IXmlSerializable «безопасно» и которые определяют неявные преобразования в тип System.

2013-06-30 18:37

Вы на самом деле не говорите об «ошибках», вы говорите о вещах, которые могут законно произойти. XML- это очень гибкий формат. Одна из проблем заключается в том, что обычные языки программирования гораздо менее гибки.

Тип гибкости, который вы ищете, встроен в XML-ориентированные языки, такие как XPath, XQuery и XSLT. Низкоуровневое программирование с использованием интерфейсов DOM — это действительно тяжелая работа по сравнению с XPath по тем причинам, которые вы обнаруживаете.

2013-06-30 20:21

Понравилась статья? Поделить с друзьями:
  • Обработка ошибок перевод на английский
  • Обработка ошибок и исключения java
  • Обработка ошибок и исключений коды ошибок
  • Обработка ошибок python яндекс практикум
  • Обработка ошибок запросов в php