【问题标题】:how to read and change the xml file in C#如何在 C# 中读取和更改 xml 文件
【发布时间】:2012-04-18 18:08:52
【问题描述】:

非常感谢您阅读我的问题。

这是我的 xml 文件。 (对于节点 Songs,有很多名为 Song 的子节点)

<?xml version="1.0" encoding="utf-8" ?>
<xmlData>
    <version>1.0</version>
    <Songs>
        <Song>
            <artist>mic</artist>
            <track>2</track>
            <column>happy</column>
            <date>14</date>
        </Song>
        <Song>
            <artist>cool</artist>
            <track>2</track>
            <column>work</column>
            <date>4</date>
        </Song>
    </Songs>
</xmlData>

读取xml,我使用以下代码:

        XmlDocument doc = new XmlDocument();
        doc.Load(xmlFilePath);

        XmlNode versionNode = doc.SelectSingleNode(@"/xmlData/version");
        Console.WriteLine(versionNode.Name + ":\t" + versionNode.InnerText);

        XmlNode SongsNode = doc.SelectSingleNode(@"/xmlData/Songs");
        Console.WriteLine(SongsNode.Name + "\n");

        XmlDocument docSub = new XmlDocument();
        docSub.LoadXml(SongsNode.OuterXml);

        XmlNodeList SongList = docSub.SelectNodes(@"/Songs/Song");

        if (SongList != null)
        {
            foreach (XmlNode SongNode in SongList)
            {
                XmlNode artistDetail = SongNode.SelectSingleNode("artist");
                Console.WriteLine(artistDetail.Name + "\t: " + artistDetail.InnerText);

                XmlNode trackDetail = SongNode.SelectSingleNode("track");
                Console.WriteLine(trackDetail.Name + "\t: " + trackDetail.InnerText);

                XmlNode columnDetail = SongNode.SelectSingleNode("column");
                Console.WriteLine(columnDetail.Name + "\t: " + columnDetail.InnerText);

                XmlNode dateDetail = SongNode.SelectSingleNode("date");
                Console.WriteLine(dateDetail.Name + "\t: " + dateDetail.InnerText + "\n");

            }
        }

它似乎工作。 但是如何将更改写入 xml 文件? 也许,我会在 Song 中更改一些 childNode,并可能通过艺术家关键字删除整个 chindNode。

有没有可能像这个功能 bool DeleteSongByArtist(string sArtist); bool ChangeNodeInSong(string sArtist, string sNodeName, string value);

因为“读取解决方案是“XmlDucoment”,所以最好使用“XmlDocument”“改变解决方案”

但是,如果您对阅读和更改 xml 文件有更好的想法,请给我示例代码...请不要写解决方案的名称,例如“Ling to xml”...实际上,我做了很多睾丸,但都失败了。

【问题讨论】:

  • 或者干脆 doc.Save(newFileName);
  • @erlvde:您在代码中途创建了一个全新的 XmlDocument 有什么原因吗?假设这是一个错误,我已经回答了(因为我无法预见任何有用的理由这样做)。

标签: c# .net xml


【解决方案1】:

欢迎使用 Stackoverflow!

您只需设置一个新的.Value 或在您的情况下为.InnerText 即可更改节点。

示例

// change the node
trackDetail.InnerText = "NewValue"
// save the document
doc.Save(xmlFilePath);

更多信息

【讨论】:

  • 感谢您的回答,但如果更改,我认为必须先找到它,然后为 InnerText 设置新值,但是如何保存呢?例如我的示例代码中的“docSub”,如果 docSub.Save(),它只保存临时内存“docSub”,而不是“doc”。我认为,只有 doc 可以更改硬盘中的 xml 文件。你怎么看?
  • @erlvde 我不明白。您可以使用Save 方法保存文件。
  • 嗯..真的很抱歉,但我不知道“保存”。我可以通过 XmlDocument 读取 xml,也可以通过 set 方法更改内部文本。对于“version”标签,我们可以在“doc”中更改它(请我的代码),但是对于“song”标签,它不在“doc”中而是在“docSub”中,这就是我困惑的原因。如果保存,应该保存“doc”,但在“docSub”中更改。
  • 您是否尝试保存更改 docSub 并保存文档?有用吗?
  • 您的意思是,更改“docSub”然后保存“doc”,xml 将保存在硬盘中?抱歉,我对此一无所知。我稍后会尝试,我现在在公共汽车上,无法编译代码。但还有一件事,“改变”不仅仅是“改变一些节点的内部文本”,如何删除“歌曲”,或者如何添加“歌曲”?非常感谢您的帮助。
【解决方案2】:

您需要使用 XmlWriter。最简单的方法是这样的......

using(XmlWriter writer = new XmlWriter(textWriter))
{
   doc.WriteTo(writer);
}

其中 textWriter 是您初始化的文本编写器。

其实,忘了...最简单的方法就是调用...

doc.Save(xmlFilePath);

要按艺术家名称删除艺术家,请添加以下方法:

    bool DeleteSongByArtist(XmlDocument doc, string artistName)
    {
        XmlNodeList SongList = doc.SelectNodes(@"/Songs/Song");
        if (SongList != null)
        {
            for (int i = SongList.Count - 1; i >= 0; i--)
            {
                if (SongList[i]["artist"].InnerText == artistName && SongList[i].ParentNode != null)
                {
                    SongList[i].ParentNode.RemoveChild(SongList[i]);
                }
            }

        }
    }

您可能希望对其进行更多清理以使其更具弹性。当您调用它时,将您的初始代码更改为这样。不要创建subDocument,因为您想使用整个 XmlDocument。

    XmlDocument doc = new XmlDocument();
    doc.Load(xmlFilePath);

    XmlNode versionNode = doc.SelectSingleNode(@"/xmlData/version");
    Console.WriteLine(versionNode.Name + ":\t" + versionNode.InnerText);

    XmlNode SongsNode = doc.SelectSingleNode(@"/xmlData/Songs");
    Console.WriteLine(SongsNode.Name + "\n");

    XmlNodeList SongList = doc.SelectNodes(@"/Songs/Song");

    if (SongList != null)
    {
        foreach (XmlNode SongNode in SongList)
        {
            XmlNode artistDetail = SongNode.SelectSingleNode("artist");
            Console.WriteLine(artistDetail.Name + "\t: " + artistDetail.InnerText);

            XmlNode trackDetail = SongNode.SelectSingleNode("track");
            Console.WriteLine(trackDetail.Name + "\t: " + trackDetail.InnerText);

            XmlNode columnDetail = SongNode.SelectSingleNode("column");
            Console.WriteLine(columnDetail.Name + "\t: " + columnDetail.InnerText);

            XmlNode dateDetail = SongNode.SelectSingleNode("date");
            Console.WriteLine(dateDetail.Name + "\t: " + dateDetail.InnerText + "\n");

        }
    }

【讨论】:

  • 谢谢。 xmlWriter ..acutally,我之前尝试过。在我们保存之前,我们必须先在我的代码中更改“doc”。所以问题是:1:如何更改“doc”? 2:如何给xmlwriter赋doc值?
  • 对于 #1) 抱歉,我会更新我的代码。对于#2)第一个示例将文档写入 xml writer(第二个不需要 xmlwriter)。
  • 更新了您的删除问题。您将使用类似的方法来更改文本,而不是删除节点更改您想要更改的任何 Xml。
【解决方案3】:

您无法保存更改,因为您对一个全新的文档进行了更改!

您可能打算执行以下操作:

XmlNode SongsNode = doc.SelectSingleNode(@"/xmlData/Songs");
Console.WriteLine(SongsNode.Name + "\n");

// Don't make a new XmlDocument here! Use your existing one
XmlNodeList SongList = SongsNode.SelectNodes(@"/Song");

此时SongList 仍然住在里面 doc。现在当你打电话时:

doc.Save(xmlFilePath);

您的更改将按预期保存。

如果您要删除符合特定条件的节点:

// Use XPath to find the matching node
XmlNode song = SongsNode.SelectSingleNode(@"/Song[artist='" + artist + "']");

// Remove it from its Parent
SongsNode.RemoveChild(song);

如果您要添加新节点:

// Create the new nodes using doc
XmlNode newSong = doc.CreateElement("Song");

XmlNode artist = doc.CreateElement("artist");
artist.InnerText = "Hello";

// Begin the painstaking process of creation/appending
newSong.AppendChild(artist);

// rinse...repeat...

// Finally add the new song to the SongsNode
SongsNode.AppendChild(newSong);

【讨论】:

  • 谢谢你,我明白你的意思了。那是我对我的代码感到困惑,因为我当时制作了一个新的 XmlDocument,我不知道如何保存它。你能再帮我一个问题吗?如何删除孩子的“歌曲”或添加“歌曲”?如 bool DeleteSongByArtist(string sArtist); bool ChangeNodeInSong(string sArtist, string sNodeName, string value);
  • 我已经更新了我的答案,向您展示如何查找和删除节点,以及如何添加新节点。
【解决方案4】:

你可以做到

        XmlNodeList SongList = doc.SelectNodes(@"//Songs/Song");

// 告诉它选择文档中任意位置的 Songs 节点。这比

        doc.SelectNodes(@"/document/level1/music/Songs")

请注意,上述声明显然不是针对您的 xml,而是为了证明关于 //
的观点 使用 // 消除了对 docSub 文档和 SongsNode 元素的需要。 要添加然后删除歌曲,只需使用以下

        XmlDocument doc = new XmlDocument();
        XmlElement ea = doc.SelectSingleNode("//songs");
        XmlElement el = doc.CreateElement("song");
        XmlElement er;
        ea.AppendChild(el);
        //doing my work with ea
        //you could use innerxml.
        el.InnerXml = "<artist>Judas Priest</artist><track>7</track><column>good</column><date>1</date>";
        //or you can treat each node as above
        er = doc.CreateElement("Name");
        el.AppendChild(er);
        er.InnerText = "The Ripper";
        //but you don't nead this song any more?
        ea.RemoveChild(el);
        //so it's gone.

这就是它的全部内容。

【讨论】:

    【解决方案5】:

    请不要写“Ling to xml”之类的解决方案名称...实际上,我做了很多睾丸,但都失败了。

    我仍然认为,现在是开始使用 Linq2Xml 的好时机。如果你不喜欢它,请忽略它。

    XDocument xDoc = XDocument.Load(new StringReader(xml));
    
    //Load Songs
    var songs = xDoc.Descendants("Song")
                    .Select(s => new
                    {
                        Artist = s.Element("artist").Value,
                        Track = s.Element("track").Value,
                        Column = s.Element("column").Value,
                        Date = s.Element("date").Value,
                    })
                    .ToArray();
    
    //Delete Songs
    string songByArtist="mic";
    xDoc.Descendants("Song")
        .Where(s => s.Element("artist").Value == songByArtist)
        .Remove();
    string newXml = xDoc.ToString();
    

    【讨论】:

    • 呵呵。我不想抱怨......但事实是......我工作了很多天,很少休息......我的大脑对新事物很糟糕......如果方便的话,我会问你更多是否学习“Ling” "。
    猜你喜欢
    • 1970-01-01
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    相关资源
    最近更新 更多