Парсинг xml строка к xml документу перестал работать, если строка начинается с раздела <? xml …?>

У меня есть XML-файл, начинающийся как это:

<?xml version="1.0" encoding="utf-8"?>
<Report xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition">
  <DataSources>

Когда я выполняю следующий код:

byte[] fileContent = //gets bytes
            string stringContent = Encoding.UTF8.GetString(fileContent);
            XDocument xml = XDocument.Parse(stringContent);

Я получаю следующий XmlException:

Данные на корневом уровне недопустимы. Строка 1, положение 1.

Включение версии и кодирование узла решают проблему. Почему? Как обработать этот xml правильно?

27
задан Kolky 17 July 2012 в 13:34
поделиться

4 ответа

Если у вас есть только байты, вы можете либо загрузить байты в поток:

XmlDocument oXML;

using (MemoryStream oStream = new MemoryStream(oBytes))
{
  oXML = new XmlDocument();
  oXML.Load(oStream);
}

или вы Может ли преобразовать байты в строку (предполагаю, что вы знаете кодировку) перед загрузкой XML:

string sXml;
XmlDocument oXml;

sXml = Encoding.UTF8.GetString(oBytes);
oXml = new XmlDocument();
oXml.LoadXml(sXml);

Я показал мой пример как .NET 2.0, совместимый, если вы используете .NET 3.5. Вы можете использовать XDocument вместо XMLDocument .

Загрузите байты в поток:

XDocument oXML;

using (MemoryStream oStream = new MemoryStream(oBytes))
using (XmlTextReader oReader = new XmlTextReader(oStream))
{
  oXML = XDocument.Load(oReader);
}

Преобразуйте байты в строку:

string sXml;
XDocument oXml;

sXml = Encoding.UTF8.GetString(oBytes);
oXml = XDocument.Parse(sXml);
17
ответ дан 28 November 2019 в 04:50
поделиться

Почему беспокоиться, чтобы прочитать файл в качестве последовательности байтов, а затем преобразовывать его в строку, когда это файл XML? Просто оставьте рамки сделать загрузку для вас и справиться с кодировками:

var xml = XDocument.Load("test.xml");
8
ответ дан 28 November 2019 в 04:50
поделиться

У вас есть байт-маркет (BOM) в начале вашего XML, и соответствует ли он вашим кодировке? Если вы нарезаете свой заголовок, вы также поручите BOM, и если это неверно, то последующие разборы могут работать.

Вам может потребоваться осмотреть ваш документ на уровне байта, чтобы увидеть BOM.

7
ответ дан 28 November 2019 в 04:50
поделиться

Моей первой мыслью было, что при разборе XML с .NET-строковым типом кодировка является Unicode. Похоже, что парсинг XDocument довольно прощающий в этом отношении.

Проблема на самом деле связана с меткой преамбулы/байтового порядка UTF8 (BOM), которая представляет собой трехбайтовую сигнатуру , опционально присутствующую в начале потока UTF-8. Эти три байта являются подсказкой о кодировке, используемой в потоке.

Преамбулу кодировки можно определить, вызвав метод GetPreamble на экземпляре класса System.Text.Encoding . Например:

// returns { 0xEF, 0xBB, 0xBF }
byte[] preamble = Encoding.UTF8.GetPreamble();

Преамбула должна быть корректно обработана с помощью XmlTextReader, поэтому просто загрузите свой XDocument из XmlTextReader:

XDocument xml;
using (var xmlStream = new MemoryStream(fileContent))
using (var xmlReader = new XmlTextReader(xmlStream))
{
    xml = XDocument.Load(xmlReader);
}
25
ответ дан 28 November 2019 в 04:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: