Hello i am working on creating XmlDocument with product data. My code
foreach (var pv in pvs)
{
XmlElement product = xml.CreateElement("Product");
product.SetAttribute("SKU", pv.Sku);
root.AppendChild(product);
var pname = xml.CreateElement("Name");
pname.InnerText = pv.Product.Name;
product.AppendChild(pname);
var MRP = xml.CreateElement("Mrp");
MRP.InnerText = Math.Round(pv.OldPrice, 2).ToString();
var SKU_MRP = _barcodeService.GetMRPsBySku(pv.Sku);
var mrps = SKU_MRP.AsEnumerable().Select(s => s.MRP).ToList();
if (mrps.Count > 0)
{
mrpstring = string.Join<string>(",", mrps.Select(x => Math.Round(x, 2).ToString()).Where(x => x != Math.Round(pv.OldPrice, 2).ToString()).ToList());
}
if (!string.IsNullOrEmpty(mrpstring))
{
MRP.InnerText += "," + mrpstring;
}
product.AppendChild(MRP);
}
xml.Save(path);
Above code I have pasted is only part of my whole function. Note that I am calling method from my function of barcodeservice which returns IList.
My pv
count exceeds 5000. So it taked 5-7 minutes to generate complete file.
Now is there any workaround to this to minimize load or how can i generate same file without using foreach.
Any Solutions?
If you need to generate big xml file, then use XmlWriter
instead of XmlDocument
. XmlDocument
builds in-memory xml representation before you can save it to file. XmlWriter
writes data directly to file.
With XmlWriter
your loop will look like:
using(XmlWriter writer = XmlWriter.Create(fileName))
{
writer.WriteStartDocument();
writer.WriteStartElement("Products");
foreach (var pv in pvs)
{
writer.WriteStartElement("Product");
writer.WriteAttributeString("SKU", pv.Sku);
writer.WriteElementString("Name", pv.Product.Name);
// ...
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteEndDocument();
}
Also you can optimize mrpstring
creation (if price is stored as decimal value):
decimal oldPrice = Math.Round(pv.OldPrice, 2);
var SKU_MRP = _barcodeService.GetMRPsBySku(pv.Sku);
var newPrices = SKU_MRP.AsEnumerable()
.Select(s => Math.Round(s.MRP, 2))
.Where(mrp => mrp != oldPrice);
mrpstring = String.Join(",", newPrices);
Thus you need only enumerate new prices, then you don't need to save them to list, also you don't need to check count, because if there is nothing to join, join will return empty string. Also if you are using decimals
for price, then avoid converting them to strings, or consider make rounding only during mrpstring
creation.