金蝶云星空-开发篇:XML转换
最近公司正在升级ERP系统,异构系统的集成主要是自己在做,在编写代码过程中,自己有一些心得,记录一下自己在开发过程中的一点小问题,欢迎大家相互讨论;
一.接口参数传递
- XML参数传递
起初在刚开始思考参数传递的时候,也想过用XML文本传输格式进行异构传递,但是XML个人觉得比较麻烦,因为XML在数据传输中占用的数据流内存比较大,涉及到数据量较大时,在网上查询通用的方法一般是写成XML的TXT文档,三方接口需要加载文档读取XML数据,加载方法如下:
static void Main(string[] args) { //将XML文件加载进来 XDocument document = XDocument.Load("D:\\123.xml"); //获取到XML的根元素进行操作 XElement root= document.Root; XElement ele= root.Element("BOOK"); //获取name标签的值 XElement shuxing= ele.Element("name"); Console.WriteLine(shuxing.Value); //获取根元素下的所有子元素 IEnumerable<XElement> enumerable = root.Elements(); foreach (XElement item in enumerable) { foreach (XElement item1 in item.Elements()) { Console.WriteLine(item1.Name); //输出 name name1 } Console.WriteLine(item.Attribute("id").Value); //输出20 } Console.ReadKey(); }
这种情况一般是清楚XML的结构,但是在本次项目开发过程中涉及到:致远OA接口较多,并且提供的DEE程序,需要你编写SQL语句之后,查询出你需要的信息,如果针对每次的XML都进行接口定制拆分,这样感觉自己一直在搬砖,所以自己就想着把传入的XML转换成动态结构化数据,形成一个公用方法,第一步根据XML动态转换为Datatable,第二步对结构化数据进行表操作方便快捷,第三转换回XML传回给OA,具体操作如下:
1.XML动态转换Datatable
- 根据XML的遍历,定义表结构,然后赋值
public static DataTable XmlToDataTableByString(string xmlString) { XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlString); DataTable dt = new DataTable(); //因为致远OA的DEE传出的DOC 文件格式比较特殊,所对数据以第一个元素row的子元素建立表结构,上级参数一律忽略 XmlNode rowNode = doc.SelectSingleNode("//row[1]"); if (rowNode != null) { for (int i = 0; i < rowNode.ChildNodes.Count; i++) { string colName; //定义表结构的列名称,根据XML文件来 colName = rowNode.ChildNodes.Item(i).Name; dt.Columns.Add(colName); } //循环遍历增加数据 XmlNodeList rowNodes = doc.SelectNodes("//row"); foreach (XmlNode item in rowNodes) { DataRow dRow = dt.NewRow(); foreach (XmlElement ie in item) { dRow[ie.Name] = ie.InnerText; } dt.Rows.Add(dRow); } } return dt; }
2.表结构的操作再次不在详细说明,因为基本上都是标准用法,循环/取值/更新等等;
//1.创建空列 DataColumn dc = new DataColumn(); dt.Columns.Add(dc); //2.创建带列名和类型名的列(两种方式任选其一) dt.Columns.Add("column0", System.Type.GetType("System.String")); dt.Columns.Add("column0", typeof(String)); //3.通过列架构添加列 DataColumn dc = new DataColumn("column1",System.Type.GetType("System.DateTime")); DataColumn dc = new DataColumn("column1", typeof(DateTime)); dt.Columns.Add(dc); //实际在程序中用到的地方,在这里记录一下 try { requestData = CommonMethod.JsonToDataTable(para); //MesServiceReference.K3ServiceSoapClient MesClient = new MesServiceReference.K3ServiceSoapClient(); foreach (DataRow item in requestData.Rows) { string eResult = eBoardService.ProductionOrderSplit(item["icmWorkNo"].ToString()); switch (eResult) { case "0": item.SetField("icmoResult", "成功发布分解"); break; case "1": item.SetField("icmoResult", "任务单未推送MES"); break; case "2": item.SetField("icmoResult", "任务单号为空"); break; case "3": item.SetField("icmoResult", "MES分解未成功"); break; default: item.SetField("icmoResult", "非整机类型任务单"); break; } //SetField:用于更新datatable的某行中某列的值 } }
3.处理完的Datatable传递给其他系统或者进行OA自定义的DOC要求的XML格式转换,这里只把自己转换回XML的方法记录一下;
public static string DatatableToDoc(DataTable dtt) { string doc = "<root> \n < table1 count = " + dtt.Rows.Count + " totalCount = " + dtt.Rows.Count + "> " + "\n"; for (int i = 0; i < dtt.Rows.Count; i++) { doc = doc + "<row>" + "\n"; foreach (DataColumn col in dtt.Columns) { doc = doc + "<" + col.ColumnName + "><![CDATA[" + dtt.Rows[i][col.ColumnName].ToString() + "]]></" + col.ColumnName + ">" + "\n"; } doc = doc + "</row>" + "\n"; } doc = doc + "</table1>" + "\n"; doc = doc + "</root>"; return doc; } //因为DOC要求的数据格式中,每行数据都需要有一个ROW标识,所以对表结构数据进行循环添加即可
具体在开发过程中还用到了一些具体的方法,后续会继续在这里更新!!!!大家如果有不同见解可以赐教,本人水平比较菜,正在学习中……