Csharp/C#教程:用C#编写XML分享


用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

(0)
上一篇 2021年12月28日
下一篇 2021年12月28日

精彩推荐