Разбор и удаление BOM/Preamble из XML через файловую систему

Я обрабатываю файлы XBRL и натолкнулся на кучу из них, у которых в начале стоит метка порядка байтов (BOM). Если я удаляю его вручную, я могу обработать файл без каких-либо проблем.

У меня было несколько неудачных попыток удалить спецификацию с начала файлов XML, с которых я читаю.

Это сообщение об ошибке, которое я получаю:

Данные на корневом уровне недействительны. Строка 1, позиция 1.

Первоначально я использовал XDocument.Load(filename) но это не помогло с той же ошибкой, поэтому я изменил код после получения рекомендации по синтаксическому анализу XML-строки в XML-документе, который завершается неудачно, если строка начинается с раздела , но безуспешно.

void Main()
{
    XDocument doc;
    var @filename = @"C:\accounts\toprocess\2008\Prod224_8998_00741575_20080630.xml";
    byte[] file = File.ReadAllBytes(filename);
    using (MemoryStream memory = new MemoryStream(file))
    {
        using (XmlTextReader oReader = new XmlTextReader(memory))
        {
            doc = XDocument.Load(oReader);
        }
    }
}

Файл XML можно найти здесь: http://s000.tinyupload.com/download.php?file_id=92333278767554773703&t=9233327876755477370347742

2 ответа

Решение

C3 AF C2 BB C2 BF выглядит как двойная кодировка UTF-8. Кодировка UTF-8 спецификации EF BB BF, Если бы вы рассматривали каждый из них как отдельный символ и кодировали UTF-8, вы бы получили последовательность, которую вы видите.

Таким образом, документ, который у вас есть, сломан. Что-то берет документ, содержащий спецификацию UTF-8, и рассматривает его как расширенный ASCII. Если вы не можете исправить документы в источнике, я склонен искать эту конкретную последовательность в начале файла и удалять ее, если она есть.

Если в рассматриваемых документах используются другие расширенные символы ASCII, есть большая вероятность, что они тоже будут разбиты.

Последовательность C3 AF C2 BB C2 BF не похожа ни на какую спецификацию

Вам, вероятно, следует выяснить, что это такое, если оно согласовано (по длине) и т. Д.

На самом деле, вы можете просто пропустить первые 6 байтов:

using (var stream = File.Open(fileName, FileMode.Open))
{
    stream.Seek(6, SeekOrigin.Begin);
    var doc = XDocument.Load(stream);
    // ...use it
}
Другие вопросы по тегам