【发布时间】:2008-11-25 12:08:52
【问题描述】:
在 .NET 中创建 XML 文档似乎有很多选择。最好的方法是什么?
【问题讨论】:
在 .NET 中创建 XML 文档似乎有很多选择。最好的方法是什么?
【问题讨论】:
如果您只需要生成 XML(不需要解析或编辑),最快的方法是使用 XmlWriter(它比使用字符串的第二个示例更优雅、更快,而且更不容易出错,因为您不需要不必担心保持文档格式正确):
// Create an XmlWriterSettings object with the correct options.
var settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = ("\t");
settings.OmitXmlDeclaration = true;
// Create the XmlWriter object and write some content.
using (var writer = XmlWriter.Create("data.xml", settings))
{
writer.WriteStartElement("book");
writer.WriteElementString("item", "tesing");
writer.WriteEndElement();
writer.Flush();
}
如果您已经有一个要序列化的对象模型,您可以考虑使用 XmlSerializer,但是 - 至少从我的经验来看 - 它比 XmlWriter 慢得多,并且仅在简单的对象模型上易于使用。
【讨论】:
XmlWriter 有一个很好的界面,用于以流式、只进的样式创建文档。如果您有一个需要映射到 XML 的递归结构,则效果最好。
我只会将 DOM API 用作最后的手段。正如 Jon 所说,LINQ to XML 是另一种方式。但是,无论您做什么,都不要退回到字符串格式,因为您需要正确处理名称空间、实体引用、属性引用等微妙之处。
【讨论】:
如果可能的话,我会亲自使用 LINQ to XML。它比 DOM API 好得多。当然,它确实依赖于您使用 .NET 3.5...
请注意,如果您有任何需要转义的文本,您的 String.Format 解决方案就会崩溃。诚然,我想不出任何汽车品牌和型号,包括 & 或 < 等,但在更一般的情况下,这是一个真正的问题。
【讨论】:
另一种方法是使用 Xml 序列化:只需创建代表(复杂)元素的类,填充代表这些元素内容的公共属性,可能使用属性提供有关布局的其他信息:[XmlElement()] , [XmlAttribute()],... 并使用 XmlSerializer 创建文档:
public class Car
{
public string Make;
public string Model;
}
public class Cars
{
[XmlElement("Car")]
public Car[] cars;
}
class Program
{
public static void Save(Cars cars, string sFilename)
{
try
{
XmlSerializer ser = new XmlSerializer(cars.GetType());
FileStream fs = new FileStream(sFilename, FileMode.Create);
ser.Serialize(fs, cars);
fs.Close();
}
catch (Exception ex)
{ // Failed to save data to disk.
Debug.WriteLine(string.Format("Failed to save contents of {0}: {1}", sFilename ,ex.Message));
}
}
}
【讨论】:
使用 Visual Studio 2008 中的 PasteXmlAsLinq 示例。打开 C:\Program Files\Microsoft Visual Studio 9.0\Samples\1033\CSharpSamples.zip 并提取 LinqSamples\PasteXmlAsLinq 文件。自述文件告诉您如何设置和使用它。
【讨论】:
我还没做,但是VB的XML Literals。
【讨论】:
string.format(或任何其他形式的字符串连接)显然是一种代码味道,在实践中更加不透明,更容易出现人为错误,更难分解,因此更难维护,并且比DOM 方法。
我强烈建议使用 DOM 方法。
【讨论】:
您是否考虑过使用 XML 序列化,并将您的类序列化为 XML 文件
【讨论】:
如果您有可用于 XML 文档的架构文件,您可以使用 xsd 工具为您生成类,然后使用序列化来读取和写入 XML 文件。
【讨论】:
我正在进行的当前项目,我有很多信息需要存储在 xml 中。我没有继续使用上面定义的任何方法,而是创建了自己的包装器来为我工作。我建议你也这样做。付出一次努力,然后一遍又一遍地使用它。我是 Fluent Interface 的忠实粉丝,因此我的 api 可以相应地工作。这是一个例子
List<string> hierarchyList = new List<string>();
hierarchyList.Add("Book");
hierarchyList.Add("Product");
ConfigurationManager manager = new ConfigurationManager();
manager.FileName = "deleteme.xml";
expression = new ConfigurationManagerExpression(manager);
expression.AddNode("HierarchySet");
// ROOT_NODE_CONSTANT is the root node of document
string nodePath = manager.ROOT_NODE_CONSTANT + "/HierarchySet";
foreach (string name in hierarchyList)
{
expression.UsingNode(nodePath).AddNode("HierarchyName").AssignValue(name);
}
string panelPrefix = "PE";
string pathWithFileName = "define your path here";
manager.SaveSettings(pathWithFileName );
Let me know if you need code and I"ll post it on my blog (which I need to do eventually).
【讨论】:
使用 MVP.XML 中的 XML Typed Templates。
【讨论】:
只使用API,有很多CreateElement、AppendChild等方法:
XmlNode carNode = xmlDocument.CreateElement("Car");
xmlDocument.DocumentElement.AppendChild(carNode);
XmlNode makeNode = xmlDocument.CreateElement("Make");
carNode.AppendChild(makeNode);
...
【讨论】:
为文档的每个组件使用一个字符串。文档的值由 String.Format 插入,然后 LoadXml 将其转换为 XmlDocument:
string carString =
"<Car>" +
" <Make>{0}</Make>" +
" <Model>{1}</Model>" +
"</Car>";
XmlDocument carDoc = new XmlDocument();
carDoc.LoadXml(String.Format(carString, make, model));
【讨论】: