前提
可能是组长看我太闲了,所以给我派了个活,解析xml,然后存入到数据库中。当我打开xml的时候瞬间不开心了,因为乱糟糟的,而且一下看不到文档的尽头,后来仔细看看,发现数据量1w,瞬间觉得这是个小挑战了。不管数据量的问题了,还是先把xml解析出来吧。保留了文件中的所有节点,删除了大部分数据,留下几条,方便测试。
解析
解析过程,直接上代码了啊,代码中有注释,有需要的自行查看,不懂的欢迎留言提问。
#region 解析xml文件,加载到list中+AnalyzeXml+贾文静+2017年3月7日09:04:23
/// <summary>
/// 解析xml文件
/// </summary>
/// <returns></returns>
private List<GOODS_DRUGCODE> AnalyzeXml()
{
XmlDocument doc = new XmlDocument();
//防止xml文件中有注释,造成解析失败
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;
XmlReader reader = XmlReader.Create(path, settings);
//加载文件路径
doc.Load(reader);
//存入到实体list中
List<GOODS_DRUGCODE> goodDrugCodeLists = new List<GOODS_DRUGCODE>();
//读取规定的根节点
XmlNode xnode1 = doc.SelectSingleNode("/Document/Events/Event");
//读取根节点下的所有子节点,规定根节点子节点为一级节点,之后的以此类推,二级,三级等等
XmlNodeList xnl1 = xnode1.ChildNodes;
//开始循环遍历根节点下边的一级子节点
foreach (XmlNode xn1 in xnl1)
{
GOODS_DRUGCODE goodDrugCode1 = new GOODS_DRUGCODE();
// 将节点转换为元素,便于得到节点的属性值
XmlElement xe = (XmlElement)xn1;
// 得到productCode属性的属性值
goodDrugCode1.GOODS_ID = xe.GetAttribute("productCode").ToString();
// 得到一级节点的所有子节点,即二级节点
XmlNodeList xnl2 = xe.ChildNodes;
foreach (XmlNode xn2 in xnl2)
{
GOODS_DRUGCODE goodDrugCode2 = new GOODS_DRUGCODE();
XmlElement xe1 = (XmlElement)xn2;
goodDrugCode2.BATCH_NO = xe1.GetAttribute("batchNo").ToString();
goodDrugCode2.PRODUCT_DATE = xe1.GetAttribute("madeDate").ToString();
goodDrugCode2.VALID_DATE = xe1.GetAttribute("validateDate").ToString();
XmlNodeList xnl3 = xe1.ChildNodes;
foreach (XmlNode xn3 in xnl3)
{
GOODS_DRUGCODE goodDrugCode3 = new GOODS_DRUGCODE();
//读取三级节点
XmlElement xe2 = (XmlElement)xn3;
//赋值的过程
goodDrugCode3.GOODS_ID = goodDrugCode1.GOODS_ID;
goodDrugCode3.ORG_ID = AppData.ORG_ID;
goodDrugCode3.CREATE_MAN = AppData.OPERATORNAME;
goodDrugCode3.OWNER_ID = AppData.OwnerId;
goodDrugCode3.BATCH_NO = goodDrugCode2.BATCH_NO;
goodDrugCode3.PRODUCT_DATE = goodDrugCode2.PRODUCT_DATE;
goodDrugCode3.VALID_DATE = goodDrugCode2.VALID_DATE;
goodDrugCode3.ISDELETED = "0";
goodDrugCode3.MODIFY_MAN = "";
goodDrugCode3.CODE = xe2.GetAttribute("curCode").ToString();
goodDrugCode3.ISLEAF= xe2.GetAttribute("packLayer").ToString();
goodDrugCode3.PARENT_CODE= xe2.GetAttribute("parentCode").ToString();
//读取之后,添加到list中
goodDrugCodeLists.Add(goodDrugCode3);
}
}
}
return goodDrugCodeLists;
}
#endregion
其实对于我来说,最难的部分确认根节点,没想到读取节点的时候可以连续读取。之后就是树,之前做过树的递归,主要是理清逻辑关系,其实别的就没有那么困难了哈。
引用类型VS值类型
在这个解析的过程,我想说我终于明白引用类型和值类型的区别了,在赋值遍历的过程,参数总是被覆盖,小编甚是苦恼,后来发现string引用类型的问题了,引用类型只是指向了一个地址,当地址的值被改变的时候,所有指向这个地址的引用的值都被覆盖的,引用类型调用的是内存中的地址。只想说,这个概念从我学计算机就伴随我,搞了好多次,总结了好多次,终于在这个实际问题中解决了。也明白了为什么要在遍历里面完成实例化model的过程。如果不重新new,就会造成值被不断覆盖。值类型都有一个独立的内存区域保存自己的值,调用它的时候调用的是他的值。
foreach VS for
在解析过程遍历过程中,小编用的都是foreach,是因为小编发现系统中很少用到for,所以也顺带手查了一下两个的性能,果然还是前人的选择是正确的。
区别
for 你先要给初值,末值和步长
foreach 不需要事先给定初值,末值和步长,他是自动遍历给定的集合体的所有值
性能
相对于for语句foreach具有更好的执行效率,foreach的平均花费时间只有for30%。通过测试结果在for和foreach都可以使用的情况下,推荐使用效率更高的foreach.
后续
原本我以为解析完成,可能大部分的工作量就完成了,当我还暗自高兴的时候,往下做存储的时候,我发现高兴早了,1W的数据量,在保证存储速度的前提下,还是有点小挑战的哈。感谢这个机会,存储的过程,咱们慢慢讲述,小编做了三版,最终选择了一个比较满意的。后续会写出。