【问题标题】:Creating XmlDocument without for loop创建没有 for 循环的 XmlDocument
【发布时间】:2014-01-11 10:20:54
【问题描述】:

您好,我正在使用产品数据创建 XmlDocument。我的代码

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);

我粘贴的以上代码只是我整个功能的一部分。请注意,我从返回 IList 的barcodeservice 函数调用方法。

我的pv 计数超过 5000。因此生成完整文件需要 5-7 分钟。 现在有什么解决方法可以最大程度地减少负载,或者如何在不使用 foreach 的情况下生成相同的文件。

有什么解决办法吗?

【问题讨论】:

    标签: c# foreach linq-to-xml xmldocument


    【解决方案1】:

    如果您需要生成大的 xml 文件,请使用 XmlWriter 而不是 XmlDocumentXmlDocument 在将其保存到文件之前构建内存中的 xml 表示。 XmlWriter 直接将数据写入文件。

    使用XmlWriter,您的循环将如下所示:

    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();
    }
    

    您还可以优化mrpstring 创建(如果价格存储为十进制值):

    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);
    

    这样你只需要枚举新的价格,就不需要保存到列表中,也不需要检查计数,因为如果没有要加入的东西,加入将返回空字符串。此外,如果您使用decimals 作为价格,请避免将它们转换为字符串,或者考虑仅在创建mrpstring 期间进行舍入。

    【讨论】:

    • 这样会节省时间吗?好吧,我还是会试一试
    • @NitinVarpe 是的,它也会更快
    • 感谢你的有用建议,还有一件事你不能像图片中的角色一样在你的博客fundd.blogspot.in 上“一个好的设计就像一件艺术品”
    • @NitinVarpe 好吧,大部分时间 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多