Psy Chotic Psy Chotic - 28 days ago 6
C# Question

Nesting XML Tags using Linq with Data From DB

I am trying to build an XML document using Linq, XElement and data from Database,

It's working kinda, but in my XML, I want to close the tag and start a new tag and get the results from the query to populate into for the Tag, it is complaining that my variable r in the tag is unresolved, how can I make this work, or is there a better way of building the XML. All the child elements should be under the parent , having two children and , which has their own set of children.

Here is the code below

public void GenerateXML(int id, string site, string state, string country, string bFn, string bLn, string sFn, string sLn)
{
var results = (from o in _db.Orders
where o.OrderId == id
select o).ToList();


var xmlDoc = new XElement("Order",
from r in results
select
new XElement("OrderHeader",

new XElement("SiteId", site),
new XElement("OrderId", r.OrderId),
new XElement("Time", r.OrderDate.Value),
new XElement("Subtotal", r.SubTotal),
new XElement("Shipping", ""),
new XElement("SalesTax", r.SalesTax),
new XElement("Total", r.Total),
new XElement("PaymentAmount", ""),
new XElement("PaymentMethod", ""),
new XElement("ArchiTypeAcctNum", "20001"),
new XElement("TaxExempt", r.TaxExempt),
new XElement("SpecialInstructions", r.SpecialInstructions),
new XElement("BillTo",
new XElement("BillEmail", r.BillToEmail),
new XElement("FirstName", bFn),
new XElement("LastName", bLn),
new XElement("CompanyName", r.BillCompany),
new XElement("Address1", r.BillToAddress),
new XElement("City", r.BillToCity),
new XElement("State", state),
new XElement("Country", country),
new XElement("Zip", r.BillToZip),
new XElement("Phone", r.BillToPhoneNumber)),
new XElement("ShipTo",
new XElement("FirstName", sFn),
new XElement("LastName", sLn),
new XElement("CompanyName", r.ShipCompany),
new XElement("Address1", r.ShipToAddress),
new XElement("City", r.ShipToCity),
new XElement("State", state),
new XElement("Country", country),
new XElement("Zip", r.ShipToZip),
new XElement("Phone", r.ShipToPhoneNumber))),
new XElement("Items",
from i in r.Items
select new XElement("Item",
new XElement("SKU", i.SkuNumber),
new XElement("PROD_Name", i.ProductName),
new XElement("Description", i.Description),
new XElement("Attributes", i.Attributes),
new XElement("Quantity", i.Quantity),
new XElement("UnitPrice", i.UnitPrice),
new XElement("InkColor", i.InkColor)))
);

xmlDoc.Save(Server.MapPath(@"~/Xml/Orders.xml"));
RedirectToAction("Save");
}

Answer

I wrote an extension for same purpose. I think much easier . you can just use as orders.EntityToXml();

public static class XmlExtensions
{


        public static bool EntityToXml<T>(this T entity, string filePath)
        {

            if (string.IsNullOrEmpty(filePath))
            {
                throw new ArgumentNullException(nameof(filePath));
            }

            var dir = Path.GetDirectoryName(filePath);

            if (string.IsNullOrEmpty(dir))
            {
                throw new ArgumentNullException(nameof(filePath));
            }

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }

            var serializer= new System.Xml.Serialization.XmlSerializer(typeof(T));

            using (var stream = new StreamWriter(filePath))
            {
                serializer.Serialize(stream , entity);
                return true;

            }
        }
}