如何使用LINQ to XML将新元素添加到Windows Phone 7上的现有XML文件中?(How do I add a new element to the existing XML file on Windows Phone 7 using LINQ to XML?)

在过去的几个小时里,我在Windows Phone 7上使用LINQ to XML。我只是想在现有的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更改为Create我会得到“Root元素缺失”但除此之外似乎没有任何模式根据哪个错误发生。

这似乎是我的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"))...

但他找不到档案。

我从未如此陷入生活中。 请告诉我我还能尝试什么。

For the last couple of hours I was struggling with LINQ to XML on Windows Phone 7. I simply just want to add new element to an existing XML file.

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);

Generally I'm experiencing very weird behavior. Sometimes I am getting an error "Operation not permitted on IsolatedStorageFileStream.". Sometimes it is "Root element is missing" and sometimes it is "Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it." If, for example, I would change System.IO.FileMode.Open to Create I would get "Root element is missing" but apart from that there doesn't seem to be any pattern according to which error occurs.

It all seems like its my XML file which causes the problem:

<?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>

It doesn't get any simpler than that and I am absolutely sure I don't have any white spaces before the declaration in the actual XML file. And to make it all even more weird I have downloaded little sample application that uses the same technique of writing to XML file. When I try to run it I am getting a very familiar error:

Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it.

Here is link to that thread: http://mobileworld.appamundi.com/blogs/petevickers/archive/2010/12/06/windows-phone-7-linq-to-xml-corruption.aspx/

Yesterday I installed Windows Phone SDK 7.1 BETA. Could that be causing the problem?


It seems like the problem is with locating xml file in isolated storage. I have created completely new project and new xml file inside.

Thats the only code I have:

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

I'am still getting: Operation not permitted on IsolatedStorageFileStream. I have tried going into properties of file.xml changing Built action and copy to output directory but that didn't work. I tried adding:

isFile.Dispose();

I also tried adding conditional statement:

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

But he couldn't find the file.

I have never been so stuck in my life. Please advice me what else can i try.

最满意答案

您正试图保存到您加载的相同流中 - 但没有将其“倒带”到开头。 我不知道隔离存储流是否可以查找,但您可以尝试将代码更改为:

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); } }

You're trying to save to the same stream you loaded from - but without "rewinding" it to the start. I don't know whether isolated storage streams are seekable, but you can try just changing the code to:

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

Note that while we don't need to reset the size of stream in this case as we're adding content, in other cases you might need to do so in order to avoid "leftover" bits at the end of the file.

Alternatively, load the document and close the stream, then open up a new stream to the same file. Note that you should use using statements to close the streams after each use, e.g.

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); } }如何使用LINQ to XML将新元素添加到Windows Phone 7上的现有XML文件中?(How do I add a new element to the existing XML file on Windows Phone 7 using LINQ to XML?)

在过去的几个小时里,我在Windows Phone 7上使用LINQ to XML。我只是想在现有的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更改为Create我会得到“Root元素缺失”但除此之外似乎没有任何模式根据哪个错误发生。

这似乎是我的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"))...

但他找不到档案。

我从未如此陷入生活中。 请告诉我我还能尝试什么。

For the last couple of hours I was struggling with LINQ to XML on Windows Phone 7. I simply just want to add new element to an existing XML file.

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);

Generally I'm experiencing very weird behavior. Sometimes I am getting an error "Operation not permitted on IsolatedStorageFileStream.". Sometimes it is "Root element is missing" and sometimes it is "Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it." If, for example, I would change System.IO.FileMode.Open to Create I would get "Root element is missing" but apart from that there doesn't seem to be any pattern according to which error occurs.

It all seems like its my XML file which causes the problem:

<?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>

It doesn't get any simpler than that and I am absolutely sure I don't have any white spaces before the declaration in the actual XML file. And to make it all even more weird I have downloaded little sample application that uses the same technique of writing to XML file. When I try to run it I am getting a very familiar error:

Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it.

Here is link to that thread: http://mobileworld.appamundi.com/blogs/petevickers/archive/2010/12/06/windows-phone-7-linq-to-xml-corruption.aspx/

Yesterday I installed Windows Phone SDK 7.1 BETA. Could that be causing the problem?


It seems like the problem is with locating xml file in isolated storage. I have created completely new project and new xml file inside.

Thats the only code I have:

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

I'am still getting: Operation not permitted on IsolatedStorageFileStream. I have tried going into properties of file.xml changing Built action and copy to output directory but that didn't work. I tried adding:

isFile.Dispose();

I also tried adding conditional statement:

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

But he couldn't find the file.

I have never been so stuck in my life. Please advice me what else can i try.

最满意答案

您正试图保存到您加载的相同流中 - 但没有将其“倒带”到开头。 我不知道隔离存储流是否可以查找,但您可以尝试将代码更改为:

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); } }

You're trying to save to the same stream you loaded from - but without "rewinding" it to the start. I don't know whether isolated storage streams are seekable, but you can try just changing the code to:

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

Note that while we don't need to reset the size of stream in this case as we're adding content, in other cases you might need to do so in order to avoid "leftover" bits at the end of the file.

Alternatively, load the document and close the stream, then open up a new stream to the same file. Note that you should use using statements to close the streams after each use, e.g.

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); } }