Как добавить новый элемент в существующий файл XML в Windows Phone 7, используя LINQ to XML? - PullRequest
3 голосов
/ 21 сентября 2011

Последние пару часов я боролся с LINQ to XML на Windows Phone 7. Я просто хочу добавить новый элемент в существующий файл XML.

XElement newItem = new XElement("item",new XAttribute("id",3), 
                                new XElement("content","Buy groceries"),
                                new XElement("status","false"));

IsolatedStorageFile isFile = IsolatedStorageFile.GetUserStoreForApplication();
IsolatedStorageFileStream stream = new IsolatedStorageFileStream("/Items.xml", System.IO.FileMode.Open, isFile);

XDocument loadedDoc = XDocument.Load(stream);
loadedDoc.Add(newItem); 
loadedDoc.Save(stream);

Обычно я испытываю очень странное поведение. Иногда я получаю сообщение об ошибке «Операция не разрешена на IsolatedStorageFileStream.». Иногда это «Корневой элемент отсутствует», а иногда это «Неожиданное объявление XML. Объявление XML должно быть первым узлом в документе, и перед ним не должно быть символов пробела». Например, если бы я изменил System.IO.FileMode.Open на «Создать», я получил бы «Корневой элемент отсутствует», но кроме этого, похоже, не существует шаблона, по которому возникает ошибка.

Все это похоже на мой XML-файл, который вызывает проблему:

<?xml version="1.0" encoding="utf-8" ?>
<items>
   <item id="1">
      <content>Get groceries</content>
      <status>false</status>
   </item>
   <item id="2">
      <content>Wash your car</content>
      <status>true</status>
   </item>
</items> 

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

Неожиданное объявление XML. Декларация XML должна быть первым узлом в документе, и перед ней не должно быть символов пробела.

Вот ссылка на эту тему: http://mobileworld.appamundi.com/blogs/petevickers/archive/2010/12/06/windows-phone-7-linq-to-xml-corruption.aspx/

Вчера установил Windows Phone SDK 7.1 BETA. Может ли это быть причиной проблемы?


Кажется, проблема в том, чтобы найти файл xml в изолированном хранилище. Я создал совершенно новый проект и новый XML-файл внутри.

Это единственный код, который у меня есть:

// Constructor
public MainPage()
{
    InitializeComponent();
    var isFile = IsolatedStorageFile.GetUserStoreForApplication();
    var stream = isFile.OpenFile("file.xml", System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite);
}  

Я все еще получаю: Операция не разрешена в IsolatedStorageFileStream. Я попытался зайти в свойства файла file.xml, изменив встроенное действие и скопировать в выходной каталог, но это не сработало. Я попытался добавить:

isFile.Dispose();

Я также попытался добавить условное выражение:

if (isFile.FileExists("file.xml"))...

Но он не смог найти файл.

Я никогда не был так застрял в своей жизни. Пожалуйста, посоветуйте мне, что еще я могу попробовать.

1 Ответ

2 голосов
/ 21 сентября 2011

Вы пытаетесь сохранить в тот же поток, с которого вы загрузили, - но без «перемотки» его в начало.Я не знаю, можно ли искать изолированные потоки хранения, но вы можете попробовать просто изменить код на:

XDocument loadedDoc = XDocument.Load(stream);
loadedDoc.Add(newItem);
stream.Position = 0;
loadedDoc.Save(stream);

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

Либо загрузите документ и закройте поток, затем откройте новый поток в тот же файл.Обратите внимание, что вы должны использовать операторы using, чтобы закрывать потоки после каждого использования, например,

using (var isFile = IsolatedStorageFile.GetUserStoreForApplication())
{
    XDocument loadedDoc;
    using (var stream = isFile.OpenFile("/Items.xml", FileMode.Open))
    {
       loadedDoc = XDocument.Load(stream);
    }
    loadedDoc.Add(newItem); 
    using (var stream = isFile.OpenFile("/Items.xml", FileMode.Create))
    {
       loadedDoc.Save(stream);
    } 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...