可能是组长看我太闲了,所以给我派了个活,解析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 其实对于我来说,最难的部分确认根节点,没想到读取节点的时候可以连续读取。之后就是树,之前做过树的递归,主要是理清逻辑关系,其实别的就没有那么困难了哈。
在这个解析的过程,我想说我终于明白引用类型和值类型的区别了,在赋值遍历的过程,参数总是被覆盖,小编甚是苦恼,后来发现string引用类型的问题了,引用类型只是指向了一个地址,当地址的值被改变的时候,所有指向这个地址的引用的值都被覆盖的,引用类型调用的是内存中的地址。只想说,这个概念从我学计算机就伴随我,搞了好多次,总结了好多次,终于在这个实际问题中解决了。也明白了为什么要在遍历里面完成实例化model的过程。如果不重新new,就会造成值被不断覆盖。值类型都有一个独立的内存区域保存自己的值,调用它的时候调用的是他的值。
在解析过程遍历过程中,小编用的都是foreach,是因为小编发现系统中很少用到for,所以也顺带手查了一下两个的性能,果然还是前人的选择是正确的。
for 你先要给初值,末值和步长
foreach 不需要事先给定初值,末值和步长,他是自动遍历给定的集合体的所有值
相对于for语句foreach具有更好的执行效率,foreach的平均花费时间只有for30%。通过测试结果在for和foreach都可以使用的情况下,推荐使用效率更高的foreach.
原本我以为解析完成,可能大部分的工作量就完成了,当我还暗自高兴的时候,往下做存储的时候,我发现高兴早了,1W的数据量,在保证存储速度的前提下,还是有点小挑战的哈。感谢这个机会,存储的过程,咱们慢慢讲述,小编做了三版,最终选择了一个比较满意的。后续会写出。