HRESULT: 0xC00CE556 — Загрузка строки в XML

Я пытаюсь загрузить строку, содержащую XML, загруженный из SkyDrive.

XmlDocument myXML = new XmlDocument();
myXML.LoadXml(importXMLDocument);

Когда я вызываю приведенный выше код, я получаю следующую ошибку:

Исключение из HRESULT: 0xC00CE556

Это XML, который я пытаюсь преобразовать из строки и загрузить в XML-документ:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfVehicle xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <vehicle>
    <VehicleName>Tahoe</VehicleName>
    <VehicleYear>2004</VehicleYear>
    <Odometer>97742</Odometer>
    <LicensePlate></LicensePlate>
    <OilWeight>5w-30</OilWeight>
    <OilBrand></OilBrand>
    <OilQuantity>6</OilQuantity>
    <OilFilterModelNumber></OilFilterModelNumber>
    <AirFilterModelNumber></AirFilterModelNumber>
    <TirePressureAll>0</TirePressureAll>
    <TirePressureFrontRight>0</TirePressureFrontRight>
    <TirePressureFrontLeft>0</TirePressureFrontLeft>
    <TirePressureBackRight>0</TirePressureBackRight>
    <TirePressureBackLeft>0</TirePressureBackLeft>
    <OilChangedOdometer>97742</OilChangedOdometer>
    <OilChangedDate>2012-05-04T19:53:53.358-06:00</OilChangedDate>
    <NextOilChangeDate>2012-08-04T19:53:53.358-06:00</NextOilChangeDate>
    <NextOilChangeOdometer>100742</NextOilChangeOdometer>
    <TiresRotated>false</TiresRotated>
    <AirFilterChanged>false</AirFilterChanged>
    <SettingDistance>3000</SettingDistance>
    <SettingMonths>3</SettingMonths>
    <SettingReminder>true</SettingReminder>
    <SettingLiveTile>true</SettingLiveTile>
    <IsTrial>true</IsTrial>
    <VehicleId>2</VehicleId>
  </vehicle>
  <vehicle>
    <VehicleName>Mazda3</VehicleName>
    <VehicleYear>2011</VehicleYear>
    <Odometer>21504</Odometer>
    <LicensePlate>abcdefg</LicensePlate>
    <OilWeight>0w-20</OilWeight>
    <OilBrand></OilBrand>
    <OilQuantity>0</OilQuantity>
    <OilFilterModelNumber></OilFilterModelNumber>
    <AirFilterModelNumber></AirFilterModelNumber>
    <TirePressureAll>0</TirePressureAll>
    <TirePressureFrontRight>0</TirePressureFrontRight>
    <TirePressureFrontLeft>0</TirePressureFrontLeft>
    <TirePressureBackRight>0</TirePressureBackRight>
    <TirePressureBackLeft>0</TirePressureBackLeft>
    <OilChangedOdometer>21504</OilChangedOdometer>
    <OilChangedDate>2012-09-14T18:05:02.298-06:00</OilChangedDate>
    <NextOilChangeDate>2013-02-14T18:05:02.298-07:00</NextOilChangeDate>
    <NextOilChangeOdometer>26504</NextOilChangeOdometer>
    <TiresRotated>false</TiresRotated>
    <AirFilterChanged>false</AirFilterChanged>
    <OilChangeCost>64.75</OilChangeCost>
    <OilChangeNotes>need new tires - $500+</OilChangeNotes>
    <SettingDistance>5000</SettingDistance>
    <SettingMonths>5</SettingMonths>
    <SettingReminder>true</SettingReminder>
    <SettingLiveTile>true</SettingLiveTile>
    <IsTrial>false</IsTrial>
    <VehicleId>2</VehicleId>
  </vehicle>
</ArrayOfVehicle>

Обновлять:

Это код, в котором я загружаю XML-файл из SkyDrive (используя API): прошлой ночью было подтверждено, что этот процесс, когда файл загружается из SKYDrive, содержит дополнительный "?" добавляется. Ниже приведена вся моя функция, которая выполняет загрузку и вызов «LoadXml». Любая помощь приветствуется.

private async void readFileInfo(string folderId)
{
     LiveOperationResult operationResultFile =
     await client.GetAsync(folderId + "/files");

     dynamic resultFile = operationResultFile.Result;
     IDictionary<string, object> fileData = (IDictionary<string, object>)resultFile;
     List<object> files = (List<object>)fileData["data"];

     foreach (object item in files)
     {
          IDictionary<string, object> file = (IDictionary<string, object>)item;

          if (file["name"].ToString() == "ocha.txt")
          {
               LiveDownloadOperationResult DLFile =
               await client.BackgroundDownloadAsync(file["source"].ToString();


                var stream = await DLFile.GetRandomAccessStreamAsync();
                var readStream = stream.GetInputStreamAt(0);


                DataReader reader = new DataReader(readStream);
                uint fileLength = await reader.LoadAsync((uint)stream.Size);


                string content = reader.ReadString(fileLength);


                XmlDocument myXML = new XmlDocument();
                myXML.LoadXml(content.ToString());


                VM.importVehicles(content);


                break;
            }
      }
}

person webdad3    schedule 02.11.2012    source источник
comment
когда я жестко запрограммировал точную строку, не видя проблемы; интересно, вытягивает ли SkyDrive какие-то дополнительные символы (например, знак порядка байтов или что-то, что не будет заметно)   -  person Jim O'Neil    schedule 02.11.2012
comment
Я сам задаюсь этим вопросом. Есть ли что-то, что я могу сделать, чтобы очистить свою строку?   -  person webdad3    schedule 02.11.2012
comment
Скорее всего, проблема в другом коде, который создает строку importXMLDocument. Рассмотрите возможность публикации этого кода или, по крайней мере, проверьте, правильно ли вы обрабатываете спецификацию/кодирование.   -  person Alexei Levenkov    schedule 02.11.2012
comment
Убедились ли вы, что ваш content точно соответствует вашим ожиданиям, добавив точку останова и проверив ее значение?   -  person K Mehta    schedule 02.11.2012
comment
Было подтверждено, что моя строка содержит лишний ? после загрузки. Я думаю, я мог бы поискать, что лишнее? и попытайтесь удалить его перед выполнением LoadXML.   -  person webdad3    schedule 02.11.2012


Ответы (1)


Я смог воспроизвести ошибку даже при чтении локального файла. Причина ошибки в том, что DataReader помещает несколько дополнительных байтов перед содержимым. Вы не видите их в отладчике, но при помещении прочитанного содержимого, например, в Notepad++, вы получаете дополнительный вопросительный знак:

?<?xml version="1.0" encoding="utf-8"?>

Как я и подозревал, дополнительные байты были байтами метки порядка байтов (BOM) (0xEF 0xBB 0xBF (239 187 191)).

Я попытался явно установить кодировку для DataReader в UTF8, но это ничего не изменило. Кажется, это ошибка в DataReader. Кстати, вы получите ту же ошибку при чтении байтов из DataReader и попытаетесь преобразовать их с помощью Encoding.UTF8.GetString. Даже этот метод не распознает спецификацию.

Хорошо. Два обходных пути:

1) Используйте FileIO.ReadTextAsync:

string content = await FileIO.ReadTextAsync(file);

2) Используйте StreamReader:

using (var stream = await file.OpenReadAsync())
{
   using (var readStream = stream.AsStreamForRead())
   {
      using (StreamReader streamReader = new StreamReader(readStream))
      {
         string content = streamReader.ReadToEnd();
         XmlDocument doc = new XmlDocument();
         doc.LoadXml(content);
      }
   }
}

Обновление:

Метод ReadFileInfo будет выглядеть так, чтобы избежать проблемы со спецификацией. Обратите внимание, что AsStreamForRead — это метод расширения, доступный в System.IO (используйте System.IO; в вашем коде).

private async Task ReadFileInfo(string folderId)
{
   LiveOperationResult operationResultFile =
   await client.GetAsync(folderId + "/files");    

   dynamic resultFile = operationResultFile.Result;
   IDictionary<string, object> fileData = (IDictionary<string, object>)resultFile;
   List<object> files = (List<object>)fileData["data"];

   foreach (object item in files)
   {
      IDictionary<string, object> file = (IDictionary<string, object>)item; 

      if (file["name"].ToString() == "ocha.txt")
      {
         LiveDownloadOperationResult DLFile =
             await client.BackgroundDownloadAsync(file["source"].ToString());  

         using (var stream = await DLFile.GetRandomAccessStreamAsync())
         {
            using (var readStream = stream.AsStreamForRead())
            {
               using (StreamReader streamReader = new StreamReader(readStream))
               {
                  string content = streamReader.ReadToEnd();
                  XmlDocument doc = new XmlDocument();
                  doc.LoadXml(content); 

                  VM.importVehicles(content); 

                  break;
               }
            }
         }
      }
   }
}
person Jürgen Bayer    schedule 02.11.2012
comment
Спасибо за ваш ответ. Я видел это дополнение? прошлой ночью и пытался все закодировать, но не смог заставить его работать. Я попытался сопоставить ваш код с кодом API SkyDrive, который я использовал, но мне не повезло. Файловая переменная, которую я использовал, была объектом IDictionary, а не StorageFile. Я заметил, что поток и переменные readStream имеют некоторые асинхронные методы, но я также не мог заставить их работать. Есть ли способ (обновленный вопрос) изменить то, что вы мне дали, на то, что я использую? - person webdad3; 02.11.2012
comment
Я попробую сегодня вечером. - person webdad3; 02.11.2012
comment
Это стало ответом! Спасибо за вашу помощь. - person webdad3; 04.11.2012