我的XDocument保存有什么问题?

时间:2016-07-08 01:41:00

标签: c# xml linq uwp

我正在尝试使用Linq将一些更改保存回XML文件,我在SO和教程网站上看到很多这样的例子,但是由于某些原因我在xmlDoc.Save(customerXMLPath)上收到错误; line 参数1:无法转换为' string'到' System.IO.Stream'

我见过的大多数样本都是ASP.Net样本,但我不认为这会对语法产生很大影响(这是一个UWP应用程序)。有人可以告诉我我做错了吗?

private void SaveChange_Click(object sender, RoutedEventArgs e)
{
    string customerXMLPath = 
        Path.Combine(Package.Current.InstalledLocation.Path, "XML/Customers.xml");

    XDocument xmlDoc = XDocument.Load(customerXMLPath);

    var updateQuery = from r in xmlDoc.Descendants("Customer")
                      where r.Element("CustomerId").Value == txtCustomerId.Text
                      select r;

    foreach (var query in updateQuery)
    {
        query.Element("State").SetValue(txtState.Text);
    }

    xmlDoc.Save(customerXMLPath);
}

编辑:根据评论,在UWP中保存没有超载。那么这是否意味着(根据另一条评论)我必须保存为流?如果是这样的话我不会覆盖文件吗? < - 当我只是想改变一些价值时,这是没有意义的,但也许我误解了答案。

我的假设是有一种方法可以在UWP中更新XML文件,所以我只是这样做错了吗?推荐的方式是什么?顺便说一句,SQLite现在不是一个选项,因为文件必须保持XML格式

2 个答案:

答案 0 :(得分:0)

不要在Path.Combine语句中使用自己的“斜杠”标记,而是让它为您完成。因此,您知道您所使用的操作系统可以接受您的路径。

切换它:

string customerXMLPath = 
        Path.Combine(Package.Current.InstalledLocation.Path, "XML/Customers.xml");

对此:

string customerXMLPath = 
        Path.Combine(Package.Current.InstalledLocation.Path, "XML", "Customers.xml");

但这不一定是你的问题。您似乎正在尝试写入READ ONLY位置。 See this post for more。我会在这里引用答案的文字部分。

  

...问题是我们无法更新安装文件夹的文件内容,这个文件夹只读一个,所以解决方法是将你的xml文件放在我们有读写权限的文件夹中...

答案 1 :(得分:0)

我想我可能已经为此找到了解决方案,但它涉及覆盖文件。它可能很脏,但它对我有用。

我在ApplicationData.Current.LocalFolder.Path位置创建了一个xml文件。在安装目录(Package.Current.InstalledLocation.Path)中工作可能很困难,因为其中的所有文件都是沙盒,您将无权修改它们。

所以第一部分看起来像这样。

string customerXMLPath = 
Path.Combine(ApplicationData.Current.LocalFolder.Path, "XML/Customers.xml");

之后,您可以运行XDocument代码。但是不要打扰调用xmlDoc.Save(customerXMLPath),因为这在UWP应用程序中不起作用。

所以第二部分看起来像这样。就像你已经一样。

XDocument xmlDoc = XDocument.Load(customerXMLPath);

var updateQuery = from r in xmlDoc.Descendants("Customer")
                  where r.Element("CustomerId").Value == txtCustomerId.Text
                  select r;

foreach (var query in updateQuery)
{
    query.Element("State").SetValue(txtState.Text);
}

最后一部分是您必须将XDocument的内容保存到文件中,从而覆盖文件中已有的任何内容。由于这是await操作,因此建议您也使用方法asyncStorageFolderStorageFile应该用于获取位置和文件娱乐。

所以最后一部分看起来像这样。

StorageFolder storageFolder = ApplicationData.Current.LocalFolder;                
var newfile = await storageFolder.CreateFileAsync("Customers.xml",
CreationCollisionOption.ReplaceExisting);

await FileIO.WriteTextAsync(newfile, xmlDoc.ToString());

因此完整的示例将如下所示。

using System.Xml.Linq;
using Windows.Storage;
using System.IO;
using System.Linq;

private void cmdStart_Click(object sender, RoutedEventArgs e)
{
    SaveXml();
}

private async void SaveXml()
{
   string XML_DATA_FILE = "Customer.xml";
   string customerXMLPath = Path.Combine(ApplicationData.Current.LocalFolder.Path, XML_DATA_FILE);

    if (File.Exists(xmlPath))
    {             

      XDocument xmlDoc = XDocument.Load(customerXMLPath);

      var updateQuery = from r in xmlDoc.Descendants("Customer")
                  where r.Element("CustomerId").Value == txtCustomerId.Text
                  select r;

     foreach (var query in updateQuery)
     {
         query.Element("State").SetValue(txtState.Text);
     }                             

     StorageFolder storageFolder = ApplicationData.Current.LocalFolder;                
     var newfile = await storageFolder.CreateFileAsync(XML_DATA_FILE, 
     CreationCollisionOption.ReplaceExisting);

     await FileIO.WriteTextAsync(newfile, xmlDoc.ToString());                
    }            
}

我希望这会有所帮助并提供一些指导。

干杯。