Best .net Method to create an XML Doc
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:
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:
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.
I would suggest using the classes in System.Xml.Linq.dll which 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.
Here's an example of XLinq vs. System.Xml to create a DOM from scratch. Your eyes will bleed when you see the System.Xml example.
Here's a quick example of how you would use XLinq to build up part of your doc.
var xml = new XElement("Orders",
new XElement("Order",
new XAttribute("OrderNumber", 12345),
new XElement("ItemNumber", "01234567"),
new XElement("QTY", 10),
new XElement("Warehouse", "PA019")
)
);
TIP Although 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:
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")
)
);
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:
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();
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....
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!
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.