在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
最近遇到一个和国税数据交互 接口的问题,数据格式要求为XML。 示例如下: <?xml version="1.0" encoding="GBK"?> <taxXml> <head> <publicHead> <nsrsbh>ROGERROGERROGER</nsrsbh> <nsrmc>ROGER</nsrmc> <swjgDm>ROGER</swjgDm> <ksDm>ROGER</ksDm> <zgswryDm>ROGER</zgswryDm> </publicHead> </head> <clxx> <row> <swjgDm>test14</swjgDm> <ssqdjzBh>test3</ssqdjzBh> <ssqdjzCpzh>test8</ssqdjzCpzh> <ssqdjzCjh>test4</ssqdjzCjh> <ssqdjzCllx>test5</ssqdjzCllx> <ssqdjzClpp>test7</ssqdjzClpp> <ssqdjzZzl>test13</ssqdjzZzl> <ssqdjzSyxz>test11</ssqdjzSyxz> <ssqdjzSyrXm>test10</ssqdjzSyrXm> <ssqdjzSyrSfzhNsrsbh>test9</ssqdjzSyrSfzhNsrsbh> <xszmYxqZ>test15</xszmYxqZ> <dlysjyxkzBh>test1</dlysjyxkzBh> <dlysjyxkzYxqZ>test2</dlysjyxkzYxqZ> <ssqdjzCllxId>test6</ssqdjzCllxId> <ssqdjzSyxzId>test12</ssqdjzSyxzId> </row> <row> <swjgDm>test14</swjgDm> <ssqdjzBh>test3</ssqdjzBh> <ssqdjzCpzh>test8</ssqdjzCpzh> <ssqdjzCjh>test4</ssqdjzCjh> <ssqdjzCllx>test5</ssqdjzCllx> <ssqdjzClpp>test7</ssqdjzClpp> <ssqdjzZzl>test13</ssqdjzZzl> <ssqdjzSyxz>test11</ssqdjzSyxz> <ssqdjzSyrXm>test10</ssqdjzSyrXm> <ssqdjzSyrSfzhNsrsbh>test9</ssqdjzSyrSfzhNsrsbh> <xszmYxqZ>test15</xszmYxqZ> <dlysjyxkzBh>test1</dlysjyxkzBh> <dlysjyxkzYxqZ>test2</dlysjyxkzYxqZ> <ssqdjzCllxId>test6</ssqdjzCllxId> <ssqdjzSyxzId>test12</ssqdjzSyxzId> </row> </clxx> <jsyxx> <row> <swjgDm>YYYYYYYYYYYYYYYY</swjgDm> <name>ROGER</name> <sfzh>XXXXXXXXXXXXXXXX</sfzh> <jszh>test</jszh> <zjcx>ZZZZZZZZZZZZZZZZZ</zjcx> </row> <row> <swjgDm>YYYYYYYYYYYYYYYY</swjgDm> <name>ROGER</name> <sfzh>XXXXXXXXXXXXXXXX</sfzh> <jszh>test</jszh> <zjcx>ZZZZZZZZZZZZZZZZZ</zjcx> </row> </jsyxx> </taxXml> 注意:其中Row节点 可能是一个或多个。 看到这个需求,首先就要考虑 利用C# 强大的 序列化功能。根据XML 结构,将其拆分为 一下 5个类。 public class Head { public PublicHead publicHead { get; set; } } public class TruckInfo { /// <summary> /// 车辆所属税务机关代码 /// </summary> public string swjgDm { get; set; } /// <summary> /// 所有权登记证明证明编号 /// </summary> public string ssqdjzBh { get; set; } /// <summary> /// 所有权登记证明车牌照号 /// </summary> public string ssqdjzCpzh { get; set; } /// <summary> /// 所有权登记证明车架号 /// </summary> public string ssqdjzCjh { get; set; } /// <summary> /// 所有权登记证明车辆类型名称(对应车辆类型表中“所有权登记证明车辆类型名称”) /// </summary> public string ssqdjzCllx { get; set; } /// <summary> /// 所有权登记证明车辆品牌 /// </summary> public string ssqdjzClpp { get; set; } /// <summary> /// 所有权登记证明载重量(吨) /// </summary> public string ssqdjzZzl { get; set; } /// <summary> /// 所有权登记证明使用性质名称(对应使用性质表中“所有权登记证明使用性质名称”) /// </summary> public string ssqdjzSyxz { get; set; } /// <summary> /// 所有权登记证明所有人 /// </summary> public string ssqdjzSyrXm { get; set; } /// <summary> /// 所有人身份证号或纳税人识别 /// </summary> public string ssqdjzSyrSfzhNsrsbh { get; set; } /// <summary> /// 行驶证明有效期止 /// </summary> public string xszmYxqZ { get; set; } /// <summary> /// 道路运输经营许可证明证明编号 /// </summary> public string dlysjyxkzBh { get; set; } /// <summary> /// 道路运输经营许可证明有效期止 /// </summary> public string dlysjyxkzYxqZ { get; set; } /// <summary> /// 所有权登记证明车辆类型代码(对应车辆类型中“所有权登记证明车辆类型代码”) /// </summary> public string ssqdjzCllxId { get; set; } /// <summary> /// 所有权登记证明使用性质代码 (对应使用性质表中"所有权登记证明使用性质代码") /// </summary> public string ssqdjzSyxzId { get; set; } } public class PublicHead { private string _nsrsbh; private string _nsrmc; public PublicHead() { } /// <summary> /// /// </summary> /// <param name="_nsrsbh">纳税人识别号</param> /// <param name="_nsrmc">纳税人名称</param> /// <param name="_swjgDm">所属税务机关代码</param> /// <param name="_ksDm">所属科所代码</param> /// <param name="_zgswryDm">主管税务人员代码</param> public PublicHead(string _nsrsbh, string _nsrmc, string _swjgDm, string _ksDm, string _zgswryDm) { this.nsrsbh = _nsrsbh; this.nsrmc = _nsrmc; this.swjgDm = _swjgDm; this.ksDm = _ksDm; this.zgswryDm = _zgswryDm; } /// <summary> /// 纳税人识别号 /// </summary> public string nsrsbh { get { return _nsrsbh; } set { if (value.Length > 22) throw new FormatException("纳税人识别号长度大于22"); _nsrsbh = value; } } /// <summary> /// 纳税人名称 /// </summary> public string nsrmc { get; set; } /// <summary> /// 所属税务机关代码 /// </summary> public string swjgDm { get; set; } /// <summary> /// 所属科所代码 /// </summary> public string ksDm { get; set; } /// <summary> /// 主管税务人员代码 /// </summary> public string zgswryDm { get; set; } } public class DriverInfo { public string swjgDm { get; set; } public string name { get; set; } public string sfzh { get; set; } public string jszh { get; set; } public string zjcx { get; set; } } [XmlRoot("taxXml")] public class TruckWithDriverInfo { public Head head { get; set; } [XmlArrayItem("row")] [XmlArray("clxx")] public List<TruckInfo> trucks { get; set; } [XmlArrayItem("row")] [XmlArray("jsyxx")] public List<DriverInfo> Drivers { get; set; } } 序列化类大同小异,但是请注意格式:根节点没有命名空间,而且编码为GBK!而且 DriverInfo 这一块如果没有信息,则不生成节点。 真搞不懂衙门 为什么要使用GBK编码,用UTF-8不好吗? /// <summary> /// /// </summary> /// <param name="stream"></param> /// <param name="o"></param> /// <param name="encoding"></param> /// <param name="removeXmlns">true,不生成xmlns</param> /// <param name="OmitXmlDeclaration">忽略 类似<?xml version='1.0' encoding='utf-8'?></param> private static void XmlSerializeInternal(Stream stream, object o, Encoding encoding, bool removeXmlns, bool OmitXmlDeclaration) { if (o == null) throw new ArgumentNullException("对象为空"); if (encoding == null) throw new ArgumentNullException("未指定编码"); XmlSerializer serializer = null; if (o is TruckWithDriverInfo) { TruckWithDriverInfo twdi = (TruckWithDriverInfo)o; if (twdi.Drivers == null || twdi.Drivers.Count == 0) { XmlAttributes attrs = new XmlAttributes(); attrs.XmlIgnore = true;//忽略 XmlAttributeOverrides xOver = new XmlAttributeOverrides(); xOver.Add(o.GetType(), "Drivers", attrs); serializer = new XmlSerializer(o.GetType(), xOver); } } if (serializer == null) { serializer = new XmlSerializer(o.GetType()); } XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.NewLineChars = "\r\n"; settings.Encoding = encoding; settings.IndentChars = " "; settings.OmitXmlDeclaration = OmitXmlDeclaration;//true:忽略 <?xml version='1.0' encoding='utf-8'?> using (XmlWriter writer = XmlWriter.Create(stream, settings)) { if (removeXmlns)//true,不生成xmlns { XmlSerializerNamespaces _namespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] { new XmlQualifiedName(string.Empty, string.Empty) }); serializer.Serialize(writer, o, _namespaces); } else { serializer.Serialize(writer, o); } writer.Close(); } } /// <summary> /// 将一个对象序列化为XML字符串 /// </summary> /// <param name="o">要序列化的对象</param> /// <param name="encoding">编码方式</param> /// <param name="removeXmlns">是否移除根节点的命名空间,true 移除 false 保留</param> /// <param name="OmitXmlDeclaration">忽略 类似<?xml version='1.0' encoding='utf-8'?></param> /// <returns>序列化产生的XML字符串</returns> public static string XmlSerialize(object o, Encoding encoding, bool removeXmlns, bool OmitXmlDeclaration) { using (MemoryStream stream = new MemoryStream()) { XmlSerializeInternal(stream, o, encoding, removeXmlns, OmitXmlDeclaration); stream.Position = 0; using (StreamReader reader = new StreamReader(stream, encoding)) { if (OmitXmlDeclaration) { return "<?xml version='1.0' encoding='GBK'?>" + Environment.NewLine + reader.ReadToEnd(); } else { return reader.ReadToEnd(); } } } } /// <summary> /// 将一个对象按XML序列化的方式写入到一个文件 /// </summary> /// <param name="xmlString">要序列化的xml文本</param> /// <param name="path">保存文件路径</param> /// <param name="filename">生成的xml文件名</param> public static void XmlSerializeToFile(string xmlString, string path, string filename) { if (string.IsNullOrEmpty(xmlString)) throw new ArgumentNullException("xmlString"); if (string.IsNullOrEmpty(path)) throw new ArgumentNullException("path"); if (string.IsNullOrEmpty(filename)) throw new ArgumentNullException("filename"); if (!System.IO.Directory.Exists(path)) { System.IO.Directory.CreateDirectory(path); } XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlString); xmlDoc.Save(System.IO.Path.Combine(path, filename)); } 搞定! |
请发表评论