如何使用LINQ to XML在Windows Phone 7上向现有的XML文件中添加新元素?

3

在过去的几个小时里,我一直在为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, 我会得到“缺少根元素”的错误,但除此之外似乎没有任何错误发生的模式。

这一切似乎都是由我的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

你试图将数据保存到与读取数据的同一个流中,但没有将该流“倒回”到开头。我不知道隔离存储流是否可寻址,但你可以尝试更改代码为:

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

不幸的是,我的代码无法通过"XDocument loadedDoc = XDocument.Load(stream);"这一行。我收到了"缺少根元素"的错误,所以我甚至无法尝试运行它。 - Booyaches
@Booyaches:这意味着你的文件是空的。 - SLaks
@SLaks:我是“手动”创建这个文档的,所以我知道它不是空的,如果我做对了。我会在下面发布一个小截图。编辑:好的,很抱歉我还不能发布图片,我是新用户。 - Booyaches
路径看起来正确,但是 "Items.xml" 和 "/Items.xml" 之间有什么区别吗? - Booyaches
@Booyaches:这在 Visual Studio 中显示,但并不意味着它存在于独立存储中... - Jon Skeet
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接