【问题标题】:How can I append information in an XML file using LINQ in C#?如何在 C# 中使用 LINQ 在 XML 文件中附加信息?
【发布时间】:2013-05-27 16:18:15
【问题描述】:

我正在尝试在 XML 文件中写入一些信息,结构应该是:

<Scoreboard>
 <Match>
  <name>Dummy</name>
  <score>1234</score>
 </Match>
 <Match>
  <name>Sample</name>
  <score>4567</score>
 </Match>    
</Scoreboard>

问题是我只能写一个条目,如果我插入另一个“匹配”,旧的会被覆盖。

例如,如果我有:

<Scoreboard>
 <Match>
  <name>Dummy</name>
  <score>1234</score>
 </Match>
</Scoreboard>

然后我想添加另一个条目,旧条目将被删除,我将只有新条目,例如:

<Scoreboard>
 <Match>
  <name>Sample</name>
  <score>4567</score>
 </Match>
</Scoreboard>

我会知道如何在不覆盖旧条目的情况下编写新条目。

这是我的代码:

using (IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication())
        {
//If file doesn't exist, then create it.

            if (!isoStore.FileExists("scoreboard.xml"))
            {
                XDocument doc = new XDocument(new XElement("Scoreboard"));

                using (IsolatedStorageFileStream isoStream =
                   new IsolatedStorageFileStream("scoreboard.xml", System.IO.FileMode.Create, isoStore))
                {
                    doc.Save(isoStream);
                }


            }
            else
            {
//Else open it and write a new element which is a child of Scoreboard
                using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream("scoreboard.xml", System.IO.FileMode.Open, isoStore))
                {
                    XDocument doc1 = XDocument.Load(isoStream);

                    var newElement = new XElement("Match",
                        new XElement("name", VarGlobal.Name),
                        new XElement("score", VarGlobal.Score));

                    doc1.Element("Scoreboard").Add(newElement);

                    Messaggio.Text = doc1.ToString();
                }
            }
        }

【问题讨论】:

  • 如果文件存在,您将加载它并附加一个新值 - 但您不会再次保存它。所以我根本看不到文件内容将如何被替换......
  • 但是如果我不保存它,为什么我再次加载它时会看到新值?我应该如何保存它?
  • 如果您不保存它,您不会看到新值。你不会的。我怀疑问题出在isoStore.FileExists。通过调试应该可以看到。
  • if (!isoStore.FileExists("scoreboard.xml")) 检查文件是否不存在并且它可以工作,因为它第一次创建文件,第二次转到“else” " 声明,我测试过了。
  • 我确实看到了新值,它覆盖了旧值,我也测试过...

标签: c# xml linq windows-phone-7


【解决方案1】:

在这种情况下,使用 XmlSerializer 会比在 xml 中手动推送元素更有效。为您的记分卡对象建模并使用基本的序列化器和反序列化器。以下示例应该可以工作(假设您的操作方法称为 SaveXmlValue())。

public class Match
{
    public string Name { get; set; }
    public string Score { get; set; }
}

public class Scorecard
{
    public List<Match> Match { get; set; }
}

public static Scorecard DeSerialize(Stream strm)
{
    var ser = new XmlSerializer(typeof(Scorecard));
    strm.Seek(0, SeekOrigin.Begin);
    return (Scorecard)ser.Deserialize(strm);
}

public static string Serialize(Scorecard scores)
{
    var ser = new XmlSerializer(typeof(Scorecard));
    using (var strm = new MemoryStream())
    {
        var writer = XmlWriter.Create(strm, new XmlWriterSettings() { Indent = true, Encoding = System.Text.Encoding.UTF8 });
        ser.Serialize(writer, scores);
        strm.Seek(0, SeekOrigin.Begin);
        var bytes = new byte[strm.Length];
        strm.Read(bytes, 0, (int)strm.Length);
        return System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length);
    }
}

public void SaveXmlValue()
{
    Scorecard scores;
    if (isoStore.FileExists("scoreboard.xml"))
    {
        using (IsolatedStorageFileStream isoStream =
            new IsolatedStorageFileStream("scoreboard.xml", System.IO.FileMode.Open, isoStore))
        {
            scores = DeSerialize(isoStream);
        }
    }
    else
    {
        // Xml file doesn't exist, create new score card object
        scores = new Scorecard();
        scores.Match = new List<Match>();
    }

    scores.Match.Add(new Match() { Name = VarGlobal.Name, Score = VarGlobal.Score });

    var xml = Serialize(scores);
    using (IsolatedStorageFileStream isoStream =
            new IsolatedStorageFileStream("scoreboard.xml", System.IO.FileMode.Create, isoStore))
    {
        var buffer = System.Text.Encoding.UTF8.GetBytes(xml);
        isoStream.Write(buffer, 0, buffer.Length);
    }

}

【讨论】:

  • 非常感谢您的回复!!我只有一个问题......当我尝试编译它时,它说:“由于保护级别,无法访问错误 1 ​​'System.Text.Encoding.GetString(byte[])'。” ... 我究竟做错了什么?再次感谢!
  • 我已经修改了代码以支持通用版本的GetString方法。它现在应该适合你了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-30
相关资源
最近更新 更多