【发布时间】:2016-05-29 05:46:05
【问题描述】:
早安,
我正在用 C# .Net 编写一个程序来管理我商店的产品,
通过给定的链接,我可以检索一个 XML 文件,其中包含我可以在我的店面上列出的所有可能的产品。
XML 结构如下所示:
<Product StockCode="103-10440">
<lastUpdated><![CDATA[Fri, 20 May 2016 17:00:03 GMT]]></lastUpdated>
<StockCode><![CDATA[103-10440]]></StockCode>
<Brand><![CDATA[3COM]]></Brand>
<BrandID><![CDATA[14]]></BrandID>
<ProdName><![CDATA[BIG FLOW BLOWING JUNCTION FLEX BLOCK, TAKES 32, 40]]> </ProdName>
<ProdDesc/>
<Categories>
<TopCat><![CDATA[Accessories]]></TopCat>
<TopCatID><![CDATA[24]]></TopCatID>
</Categories>
<ProdImg/>
<ProdPriceExclVAT><![CDATA[30296.79]]></ProdPriceExclVAT>
<ProdQty><![CDATA[0]]></ProdQty>
<ProdExternalURL><![CDATA[http://pinnacle.eliance.co.za/#!/product/4862]]></ProdExternalURL>
</Product>
这是我正在寻找的条目:
- 上次更新时间
- 股票代码
- 品牌
- 产品名称
- 产品描述
- TopCat
- ProdImg
- ProdPriceExclVAT
- 产品数量
- ProdExternalURL
这一切都很好处理,事实上我做到了:
public ProductList Parse() {
XmlDocument doc = new XmlDocument();
doc.Load(XMLLink);
XmlNodeList ProductNodeList = doc.GetElementsByTagName("Product");
foreach (XmlNode node in ProductNodeList) {
Product Product = new Product();
for (int i = 0; i < node.ChildNodes.Count; i++) {
if (node.ChildNodes[i].Name == "StockCode") {
Product.VariantSKU = Convert.ToString(node.ChildNodes[i].InnerText);
}
if (node.ChildNodes[i].Name == "Brand") {
Product.Vendor = Convert.ToString(node.ChildNodes[i].InnerText);
}
if (node.ChildNodes[i].Name == "ProdName") {
Product.Title = Convert.ToString(node.ChildNodes[i].InnerText);
Product.SEOTitle = Product.Title;
Product.Handle = Product.Title;
}
if (node.ChildNodes[i].Name == "ProdDesc") {
Product.Body = Convert.ToString(node.ChildNodes[i].InnerText);
Product.SEODescription = Product.Body;
if (Product.Body == "") {
Product.Body = "ERROR";
Product.SEODescription = "ERROR";
}
}
if (node.ChildNodes[i].Name == "Categories") {
if (!tempList.Categories.Contains(node.ChildNodes[i].ChildNodes[0].InnerText)) {
if (!tempList.Categories.Contains("All")) {
tempList.Categories.Add("All");
}
tempList.Categories.Add(node.ChildNodes[i].ChildNodes[0].InnerText);
}
Product.Type = Convert.ToString(node.ChildNodes[i].ChildNodes[0].InnerText);
}
if (node.ChildNodes[i].Name == "ProdImg") {
Product.ImageSrc = Convert.ToString(node.ChildNodes[i].InnerText);
if (Product.ImageSrc == "") {
Product.ImageSrc = "ERROR";
}
Product.ImageAlt = Product.Title;
}
if (node.ChildNodes[i].Name == "ProdPriceExclVAT") {
float baseprice = float.Parse(node.ChildNodes[i].InnerText);
double Costprice = ((baseprice * 0.14) + (baseprice * 0.15) + baseprice);
Product.VariantPrice = Costprice.ToString("0.##");
}
}
Product.Supplier = "Pinnacle";
if (!tempList.Suppliers.Contains(Product.Supplier)) {
tempList.Suppliers.Add(Product.Supplier);
}
tempList.Products.Add(Product);
}
return tempList;
}
}
但问题是,这种方式大约需要 10 秒才能完成,而这只是我必须解析的多个此类文件中的第一个。
我正在寻找最有效的方法来解析这个 XML 文件,获取我上面提到的所有字段的数据。
编辑: 我在使用预先下载的文件副本运行时以及在运行时从服务器下载文件时对代码进行了基准测试:
使用本地副本:5 秒。
没有本地副本:7.30 秒。
【问题讨论】:
-
这里有点可疑。这不应该花费10s。你单独计时那个功能?这个 XML 文件有多大?顺便说一句,您可以将
node.ChildNodes[i].Name放入开关;如果您已经找到匹配项,则无需多次检查名称。 -
XML 文件大约 82k 行,文件大小为 3.2MB - 我正在从网络链接中检索所述文件。
-
时钟下载时间与解析xml的时间分开
-
@KazutoKirigaya 我在不到一分钟的时间内使用 XElement.Load("filename") 加载了一个 1.2GB 的文件,慢的部分很可能是下载部分而不是解析。 82kb 在今天是“非常非常小”,我建议使用 linq to XML (XElement/XDocument) 而不是旧的 XmlDocument 对象
-
在使用 XmlReader 重写之前倾听人们的声音(这有助于内存消耗 - 解析性能很少见) - 找出当前代码速度变慢的真正原因。
标签: c# xml optimization