如何在 C# 中读取和更改 XML 文件
本文关键字:XML 文件 读取 | 更新日期: 2023-09-27 18:31:36
非常感谢您阅读我的问题。
这是我的XML文件。(对于节点歌曲,许多子节点命名为宋)
<?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文件?也许,我会更改歌曲中的一些子节点,并可能通过艺术家关键字删除整个chindNode。
是否有可能像这个功能bool DeleteSongByArtist(string sArtist);bool ChangeNodeInSong(string sArtist, string sNodeName, string value);
因为"读取解决方案是"XmlDucoment",所以最好使用"XmlDocument"来"更改解决方案"
但是,如果您有更好的主意来阅读和更改XML文件,请给我示例代码...并且请不要写解决方案的名称,例如"Ling to xml"...从字面上看,我做了很多睾丸,但失败了。
欢迎来到 Stackoverflow!
您只需设置新.Value
即可更改节点,或者在您的情况下.InnerText
.
样本
// change the node
trackDetail.InnerText = "NewValue"
// save the document
doc.Save(xmlFilePath);
更多信息
- 如何:修改现有 XML 文件
- MSDN - XmlDocument.Save Method
你需要使用 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");
}
}
您无法保存更改,因为您对全新的文档进行了更改!
您可能打算执行以下操作:
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);
你可以做
XmlNodeList SongList = doc.SelectNodes(@"//Songs/Song");
//告诉它选择文档中任意位置的"歌曲"节点。这比
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.
仅此而已。
请不要写解决方案的名称,例如"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();