C# 创建 XML 文档的最佳 .net 方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2076442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best .net Method to create an XML Doc
提问by scarpacci
I am trying to figure out what the best method is for writing an XML Document. Below is a simple example of what I am trying to create off of data I am pulling from our ERP system. I have read about XMLWriter, but thought I would see if there are any other better methods. Any suggestions would be greatly appreciated.
我试图找出编写 XML 文档的最佳方法。下面是一个简单的例子,说明我试图根据我从 ERP 系统中提取的数据创建什么。我已经阅读了 XMLWriter,但我想看看是否还有其他更好的方法。任何建议将不胜感激。
Example XML:
示例 XML:
<?xml version="1.0"?>
<Orders>
<Order OrderNumber="12345">
<ItemNumber>0123993587</ItemNumber>
<QTY>10</QTY>
<WareHouse>PA019</WareHouse>
</Order>
<Order OrderNumber="12346">
<ItemNumber>0123993587</ItemNumber>
<QTY>9</QTY>
<WareHouse>PA019</WareHouse>
</Order>
<Order OrderNumber="12347">
<ItemNumber>0123993587</ItemNumber>
<QTY>8</QTY>
<WareHouse>PA019</WareHouse>
</Order>
</Orders>
采纳答案by Jon Skeet
Josh's answer shows how easy it is to create a single element in LINQ to XML... it doesn't show how it's also hugely easy to create multiple elements. Suppose you have a List<Order>
called orders
... you can create the whole document like this:
Josh 的回答显示了在 LINQ to XML 中创建单个元素是多么容易......它没有显示创建多个元素也非常容易。假设你有一个List<Order>
被调用的orders
......你可以像这样创建整个文档:
var xml = new XElement("Orders",
orders.Select(order =>
new XElement("Order",
new XAttribute("OrderNumber", order.OrderNumber),
new XElement("ItemNumber", order.ItemNumber),
new XElement("QTY", order.Quantity),
new XElement("Warehouse", order.Warehouse)
));
);
LINQ to XML makes constructing XML incredibly easy. It also has support for XML namespaces which is pretty easy too. For instance, if you wanted your elements to be in a particular namespace, you'd just need:
LINQ to XML 使构建 XML 变得异常简单。它还支持 XML 命名空间,这也很简单。例如,如果您希望元素位于特定的命名空间中,您只需要:
XNamespace ns = "http://your/namespace/here";
var xml = new XElement(ns + "Orders",
orders.Select(order =>
new XElement(ns + "Order",
... (rest of code as before)
LINQ to XML is the best XML API I've worked with... it's great for querying too.
LINQ to XML 是我使用过的最好的 XML API……它也非常适合查询。
回答by Eric Mickelsen
If your use case is simple, nothing could possibly simpler and easier to use than XmlTextWriter. That said, one alternative would be to use an XmlDocument object to create and append all of your nodes. But I think it's easier to write and maintain code that uses XmlTextWriter if you're creating a document from scratch rather than manipulating one. Using XmlTextWriter should be very straightforward:
如果您的用例很简单,那么没有什么比 XmlTextWriter 更简单易用的了。也就是说,一种替代方法是使用 XmlDocument 对象来创建和附加所有节点。但我认为,如果您从头开始创建文档而不是操作文档,那么编写和维护使用 XmlTextWriter 的代码会更容易。使用 XmlTextWriter 应该非常简单:
StringBuilder output = new StringBuilder();
XmlWriter writer = XmlWriter.Create(output);
writer.WriteProcessingInstruction("xml", "version=\"1.0\"");
writer.WriteStartElement("Orders");
//...start loop...
writer.WriteStartElement("Order");
writer.WriteAttributeString("OrderNumber", "12345");
writer.WriteElementString("ItemNumber", "0123993587");
writer.WriteElementString("QTY", "10");
writer.WriteElementString("WareHouse", "PA019");
writer.WriteEndElement();
//...loop...
writer.WriteEndElement();
writer.Close();
回答by Josh
I would suggest using the classes in System.Xml.Linq.dllwhich contain an XML DOM API that allows for easy build-up of XML structures due to the way the contructors are designed. Trying to create an XML structure using the System.Xml classes is very painful because you have to create them detached then separately add them into the document.
我建议使用System.Xml.Linq.dll中的类,其中包含一个 XML DOM API,由于构造函数的设计方式,它允许轻松构建 XML 结构。尝试使用 System.Xml 类创建 XML 结构非常痛苦,因为您必须分离创建它们,然后将它们单独添加到文档中。
Here's an exampleof XLinq vs. System.Xml to create a DOM from scratch. Your eyes will bleed when you see the System.Xml example.
这是 XLinq 与 System.Xml 从头开始创建 DOM的示例。当您看到 System.Xml 示例时,您的眼睛会流血。
Here's a quick example of how you would use XLinq to build up part of your doc.
这是一个关于如何使用 XLinq 构建部分文档的快速示例。
var xml = new XElement("Orders",
new XElement("Order",
new XAttribute("OrderNumber", 12345),
new XElement("ItemNumber", "01234567"),
new XElement("QTY", 10),
new XElement("Warehouse", "PA019")
)
);
TIPAlthough it's a little unorthodox (though no worse than some of the language butchering that has become popular lately), I have on occasion used C#'s type aliasing feature to minimize the code even further:
提示虽然它有点不正统(虽然不比最近流行的一些语言屠宰更糟糕),但我有时会使用 C# 的类型别名功能来进一步减少代码:
using XE = System.Xml.Linq.XElement;
using XA = System.Xml.Linq.XAttribute;
...
var xml = new XE("Orders",
new XE("Order",
new XA("OrderNumber", 12345),
new XA("ItemNumber", "01234567"),
new XA("QTY", 10),
new XA("Warehouse", "PA019")
)
);
回答by this. __curious_geek
I had to create following XML document having some part of it parametrized.
我必须创建以下 XML 文档,其中的某些部分已参数化。
<?xml version="1.0" encoding="utf-8"?>
<wap-provisioningdoc>
<characteristic type="BOOTSTRAP">
<parm name="NAME" value="SYNCSETTINGS" />
</characteristic>
<characteristic type="APPLICATION">
<parm name="APPID" value="w5" />
<parm name="TO-NAPID" value="INTERNET" />
<parm name="NAME" value="SYNCSETTINGS" />
<parm name="ADDR" value="http://syncserver/sync" />
<characteristic type="RESOURCE">
<parm name="URI" value="pb" />
<parm name="NAME" value="Contacts DB" />
<parm name="AACCEPT" value="text/x-vcard" />
</characteristic>
<characteristic type="RESOURCE">
<parm name="URI" value="cal" />
<parm name="NAME" value="Calendar DB" />
<parm name="AACCEPT" value="text/x-vcalendar" />
</characteristic>
<characteristic type="RESOURCE">
<parm name="URI" value="notes" />
<parm name="NAME" value="Notes DB" />
<parm name="AACCEPT" value="text/plain" />
</characteristic>
<characteristic type="APPAUTH">
<parm name="AAUTHNAME" value="username" />
<parm name="AAUTHSECRET" value="password" />
</characteristic>
</characteristic>
</wap-provisioningdoc>
And here's my code that does this with single LINQ statement.
这是我使用单个 LINQ 语句执行此操作的代码。
Make a note that creating XML document above using LINQ and saving it to XML file preserves the XML document formatting and keeps line-breaks and carriage-returns that makes the document properly tabified.
请注意,上面使用 LINQ 创建 XML 文档并将其保存到 XML 文件会保留 XML 文档格式并保留换行符和回车符,从而使文档正确制表。
public string CreateOTAXmlFile(string Username, string Password)
{
var ota = new XDocument(
new XElement("wap-provisioningdoc",
new XElement("characteristic", new XAttribute("type", "BOOTSTRAP"),
new XElement("parm", new XAttribute("name", "NAME"), new XAttribute("value", "SYNCSETTINGS"))
),
new XElement("characteristic", new XAttribute("type", "APPLICATION"),
new XElement("parm", new XAttribute("name", "APPID"), new XAttribute("value", "w5")),
new XElement("parm", new XAttribute("name", "TO-NAPID"), new XAttribute("value", "INTERNET")),
new XElement("parm", new XAttribute("name", "NAME"), new XAttribute("value", "SYNCSETTINGS")),
new XElement("parm", new XAttribute("name", "ADDR"), new XAttribute("value", "http://syncserver/sync")),
new XElement("characteristic", new XAttribute("type", "RESOURCE"),
new XElement("parm", new XAttribute("name", "URI"), new XAttribute("value", "pb")),
new XElement("parm", new XAttribute("name", "NAME"), new XAttribute("value", "Contacts DB")),
new XElement("parm", new XAttribute("name", "AACCEPT"), new XAttribute("value", "text/x-vcard"))
),
new XElement("characteristic", new XAttribute("type", "RESOURCE"),
new XElement("parm", new XAttribute("name", "URI"), new XAttribute("value", "cal")),
new XElement("parm", new XAttribute("name", "NAME"), new XAttribute("value", "Calendar DB")),
new XElement("parm", new XAttribute("name", "AACCEPT"), new XAttribute("value", "text/x-vcalendar"))
),
new XElement("characteristic", new XAttribute("type", "RESOURCE"),
new XElement("parm", new XAttribute("name", "URI"), new XAttribute("value", "notes")),
new XElement("parm", new XAttribute("name", "NAME"), new XAttribute("value", "Notes DB")),
new XElement("parm", new XAttribute("name", "AACCEPT"), new XAttribute("value", "text/plain"))
),
new XElement("characteristic", new XAttribute("type", "APPAUTH"),
new XElement("parm", new XAttribute("name", "AAUTHNAME"), new XAttribute("value", Username)),
new XElement("parm", new XAttribute("name", "AAUTHSECRET"), new XAttribute("value", Password))
)
)
)
);
ota.Save(Server.MapPath("~/OTA/") + Username + ".xml");
return (ota.ToString());
}
回答by Vibin Jith
You just right click on your code window , select InsertSnippet follow this Link
您只需右键单击您的代码窗口,选择 InsertSnippet 按照此链接
Data-Xml.....>Xml>Xmlcreate
its very easy
这很容易
回答by Vibin Jith
// Create the xml document containe
XmlDocument doc = new XmlDocument();// Create the XML Declaration, and append it to XML document
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", null, null);
doc.AppendChild(dec);// Create the root element
XmlElement root = doc.CreateElement("Library");
doc.AppendChild(root);
// Create Books
// Note that to set the text inside the element,
// you use .InnerText instead of .Value (which will throw an exception).
// You use SetAttribute to set attribute
XmlElement book = doc.CreateElement("Book");
book.SetAttribute("BookType", "Hardcover");
XmlElement title = doc.CreateElement("Title");
title.InnerText = "Door Number Three";
XmlElement author = doc.CreateElement("Author");
author.InnerText = "O'Leary, Patrick";
book.AppendChild(title);
book.AppendChild(author);
root.AppendChild(book);
book = doc.CreateElement("Book");
book.SetAttribute("BookType", "Paperback");
title = doc.CreateElement("Title");
title.InnerText = "Lord of Light";
author = doc.CreateElement("Author");
author.InnerText = "Zelanzy, Roger";
book.AppendChild(title);
book.AppendChild(author);
root.AppendChild(book);
string xmlOutput = doc.OuterXml;
The same code but using an XMLWriter to a memory stream.
XmlWriterSettings wSettings = new XmlWriterSettings();
wSettings.Indent = true;
MemoryStream ms = new MemoryStream();
XmlWriter xw = XmlWriter.Create(ms, wSettings);// Write Declaration
xw.WriteStartDocument();
// Write the root node
xw.WriteStartElement("Library");
// Write the books and the book elements
xw.WriteStartElement("Book");
xw.WriteStartAttribute("BookType");
xw.WriteString("Hardback");
xw.WriteEndAttribute();
xw.WriteStartElement("Title");
xw.WriteString("Door Number Three");
xw.WriteEndElement();
xw.WriteStartElement("Author");
xw.WriteString("O'Leary, Patrick");
xw.WriteEndElement();
xw.WriteEndElement();
// Write another book
xw.WriteStartElement("Book");
xw.WriteStartAttribute("BookType");
xw.WriteString("Paperback");
xw.WriteEndAttribute();
xw.WriteStartElement("Title");
xw.WriteString("Lord of Light");
xw.WriteEndElement();
xw.WriteStartElement("Author");
xw.WriteString("Zelanzy, Roger");
xw.WriteEndElement();
xw.WriteEndElement();
// Close the document
xw.WriteEndDocument();
// Flush the write
xw.Flush();
Byte[] buffer = new Byte[ms.Length];
buffer = ms.ToArray();
string xmlOutput = System.Text.Encoding.UTF8.GetString(buffer);
回答by marc_s
What about this : create a class "Order" and one "Orders", and then serialize those out to XML - seems a lot easier to me than creating the XML bit by bit from hand....
怎么样:创建一个“订单”类和一个“订单”,然后将它们序列化为 XML - 对我来说似乎比手动一点一点地创建 XML 容易得多......
Since you say you're pulling the data off your ERP, you probably already have objects and classes for "Order" and so on - maybe it's sufficient to put a few [XmlElement] attributes on your classes and you're good to go!
既然您说要从 ERP 中提取数据,那么您可能已经有了用于“订单”等的对象和类 - 也许在您的类上放置一些 [XmlElement] 属性就足够了,您就可以开始了!
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
namespace XmlLinqTest
{
[Serializable]
[XmlRoot(Namespace = "")]
public class Orders
{
private List<Order> _orders = new List<Order>();
/// <remarks/>
[XmlElement("Order")]
public List<Order> OrderList
{
get { return _orders; }
}
}
/// <remarks/>
[Serializable]
public class Order
{
/// <remarks/>
[XmlElement]
public string ItemNumber { get; set; }
[XmlElement]
public int QTY { get; set; }
/// <remarks/>
[XmlElement]
public string WareHouse { get; set; }
/// <remarks/>
[XmlAttribute]
public string OrderNumber { get; set; }
}
}
and in your main app something like this:
在你的主应用程序中是这样的:
Orders orders = new Orders();
Order work = new Order() { ItemNumber = "0123993587", OrderNumber = "12345", QTY = 10, WareHouse = "PA019" };
orders.OrderList.Add(work);
work = new Order() { ItemNumber = "0123993587", OrderNumber = "12346", QTY = 9, WareHouse = "PA019" };
orders.OrderList.Add(work);
work = new Order() { ItemNumber = "0123993587", OrderNumber = "12347", QTY = 8, WareHouse = "PA019" };
orders.OrderList.Add(work);
XmlSerializer ser = new XmlSerializer(typeof(Orders));
using(StreamWriter wr = new StreamWriter(@"D:\testoutput.xml", false, Encoding.UTF8))
{
ser.Serialize(wr, orders);
}
Working with objects and then serializing them out to disk seems a lot easier to me than fiddling around with XDocument and other APIs.
处理对象然后将它们序列化到磁盘对我来说似乎比摆弄 XDocument 和其他 API 容易得多。
回答by Rubens Farias
If you don't want (or can't) to use LINQ to XML
, neither to duplicate your Order
class to include XML serialization, and thinks XmlWriter
is too much verbose, you can go with plain classical XmlDocument
class:
如果您不想(或不能)使用LINQ to XML
,也不复制您的Order
类以包含 XML 序列化,并且认为XmlWriter
过于冗长,您可以使用普通的经典XmlDocument
类:
// consider Order class that data structure you receive from your ERP system
List<Order> orders = YourERP.GetOrders();
XmlDocument xml = new XmlDocument();
xml.AppendChild(xml.CreateElement("Orders"));
foreach (Order order in orders)
{
XmlElement item = xml.CreateElement("Order");
item.SetAttribute("OrderNumber", order.OrderNumber);
item.AppendChild(xml.CreateElement("ItemNumber")).Value = order.ItemNumber;
item.AppendChild(xml.CreateElement("QTY" )).Value = order.Quantity;
item.AppendChild(xml.CreateElement("WareHouse" )).Value = order.WareHouse;
xml.DocumentElement.AppendChild(item);
}
回答by Robert Rossney
There are a lot of good suggestions in this thread, but one that hasn't been mentioned: Defining an ADO DataSet
and serializing/deserializing using the ReadXml
and WriteXml
methods. This can be a very simple and attractive solution. Your XML isn't in quite the right format, but it's close.
该线程中有很多很好的建议,但没有提到的一个:定义 ADODataSet
并使用ReadXml
和WriteXml
方法进行序列化/反序列化。这可能是一个非常简单且有吸引力的解决方案。您的 XML 的格式不太正确,但很接近。
回答by Optavius
I found it largely depends how complex your original data is.
我发现这在很大程度上取决于原始数据的复杂程度。
If your data is nicely organized in objects and it is sufficient to dump it in XML, Linq is very verbose and powerful. But as soon as there are object inter-dependencies, I don't think you want to go with the Linq one-liner, as this is real pain to debug and/or extend.
如果您的数据在对象中被很好地组织起来并且以 XML 格式转储它就足够了,Linq 是非常详细和强大的。但是一旦存在对象相互依赖关系,我认为您不想使用 Linq one-liner,因为调试和/或扩展真的很痛苦。
For those cases, I'd prefer to go with XmlDocument, create a help method to facilitate adding attributes to an element (see below), and use Linq in foreach loops around the XML creation blocks.
对于这些情况,我更喜欢使用 XmlDocument,创建一个帮助方法来促进向元素添加属性(见下文),并在围绕 XML 创建块的 foreach 循环中使用 Linq。
private void XAttr(ref XmlNode xn, string nodeName, string nodeValue)
{
XmlAttribute result = xn.OwnerDocument.CreateAttribute(nodeName);
result.InnerText = nodeValue;
xn.Attributes.Append(result);
}