用C#编写XML
我的C#有点生疏,我以前从未用它编写XML。 如果我尝试编写除元素之外的任何内容,我就无法将XML写入文件。 这是我的测试代码:
var guiPath = txtGuiPath.Text; MessageBox.Show("Dumping File: " + guiPath); try { var writer = new XmlTextWriter("client_settings.xml", null); writer.WriteStartDocument(); writer.WriteComment("Config generated on 01/01/01"); writer.WriteStartElement("Config"); writer.WriteStartElement("GuiPath"); writer.WriteString(guiPath); writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndDocument(); writer.Close(); } catch (Exception ex) { MessageBox.Show(ex.Message); } MessageBox.Show("Finished Dumping");
如果guiPath为空,我会得到以下XML:
但如果guiPath中有任何文本,那么没有任何内容写入文件。 我甚至可以删除client_settings.xml文件并反复激活此代码,除非guiPath为空,否则永远不会生成XML文件。 将类似“This is a test”的内容传递给WriteString()也可以。
更新
因为我试图写出一个系统路径,这似乎是问题所在。 如果我删除所有反斜杠,它将正确地写出结果字符串,但如果我将它传递给WriteString或WriteCData,则XML根本不会写入。
更新2
事实certificate我遇到这么多问题的原因是因为XML文件是在guiPath设置的任何路径中生成的,而不是在应用程序运行的目录中生成的(所以对我来说它看起来好像没有生成在所有)。 因此,如果我将guiPath设置为’C: Program Files externalApp appName.exe’,它将XML文件保存为’C: ProgramFiles externalApp client_settings.xml’,而不是在应用的启动文件夹中。 为什么,我不知道。 我开始传递Application.StartupPath并将文件名附加到它,现在它工作得很好。
感谢您的帮助!
您可能想要检查System.Xml.Linq中的API。 这是一种更灵活的生成和编写XML的方法。 编写文档可能大致如下:
XDocument document = new XDocument(); document.Add(new XComment("Config generated on 01/01/01")); document.Add(new XElement("Config", new XElement("GuiPath", guiPath))); // var xmlWriter = new XmlTextWriter("client_settings.xml", null); // document.WriteTo(xmlWriter); // thanks to Barry Kelly for pointing out XDocument.Save() document.Save("client_settings.xml");
为什么不创建一个简单的类来保存所需的所有数据,然后使用XmlSerializer对其进行序列化,而不是逐行手动生成它? 如果需要,您甚至可以使用System.Xml.Serialization中的属性来控制输出:
using System; using System.IO; using System.Windows.Forms; using System.Xml.Serialization; namespace Foo { [XmlRoot(ElementName = "Config")] public class Config { public String GuiPath { get; set; } public Boolean Save(String path) { using (var fileStream = File.Open(path, FileMode.OpenOrCreate, FileAccess.ReadWrite)) { try { var serializer = new XmlSerializer(typeof(Config)); serializer.Serialize(fileStream, this); return true; } catch(Exception ex) { MessageBox.Show(ex.Message); // Other exception handling here return false; } } } public static Config Load(String path) { using (var fileStream = File.Open(path, FileMode.Open, FileAccess.Read)) { try { var serializer = new XmlSerializer(typeof(Config)); return (Config)serializer.Deserialize(fileStream); } catch(Exception ex) { MessageBox.Show(ex.Message); // Other exception handling here return null; } } } } }
这样,如果字符串有奇怪的字符,您就不必担心手动编码字符串 – 序列化程序会为您执行此操作。
这还有一个额外的好处,就是能够序列化回到类中,这样您就可以对结构进行强类型访问,如果您需要这样做的话。
嗯,似乎“真正的” guiPath
包含破坏XMLvalidation的字符和带有它的XmlTextWriter。
我建议你尝试.WriteCData()
(而不是.WriteString()
)
你想要输出什么? 如果您正在寻找类似的东西:
GuiPath="c:somepathhere"
然后你需要将WriteString更改为:
writer.WriteAttributeString("GuiPath", guiPath);
或者,如果你想:
c:somepathhere
然后你需要写
writer.WriteElementString("GuiPath", guiPath);
没有其他人提到它,但我认为我做得更好: 强烈考虑在using
IDisposable
实现(如XmlTextWriter
等)时使用using
语句。
这不仅对于关闭资源(例如基础流或文本编写器)很重要,而且还要确保已刷新任何缓冲区,并确保关闭任何剩余的未关闭元素。
所以,当你看到mquander的anwser时 ,请考虑一下:
using (var xmlWriter = new XmlTextWriter("client_settings.xml", null)) { // ... }
同样,在Daniel的回答中 ,不要盲目地吞下exception,并强烈考虑在File.Open
的返回值上使用using
语句(可能应该是File.OpenText
是惯用的,但是风格还有很多其他缺点。丹尼尔在撰写本文时的答案)。
我会使用System.XML.Linq.XElement类
请注意注释,但Config部分会是这样的。
XElement root = new XElement("Config"); root.Add(new XElement("GuiPath", guiPath); root.Save("client_settings.xml");
编辑: mquander的例子更好。 看那个。
在写出内容之前,您需要先解析内容,以确保它们是有效的字符串。 不幸的是,我不知道自动执行它的.NET例程 – 之前已经在这里提出了这个问题。
上述就是C#学习教程:用C#编写XML分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1005748.html