C# 序列化实体类生成XML

最近遇到一个和国税数据交互 接口的问题,数据格式要求为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; }
    }
View Code
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;
        }
    }
TruckInfo
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;
        }
    }
PublicHead
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;
        }
    }
DriverInfo
[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; }
        
    }
TruckWithDriverInfo

序列化类大同小异,但是请注意格式:根节点没有命名空间,而且编码为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">忽略 类似&lt;?xml version='1.0' encoding='utf-8'?&gt;</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">忽略 类似&lt;?xml version='1.0' encoding='utf-8'?&gt;</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));
        }
View Code

搞定!

posted on 2013-05-22 18:37  weblogical  阅读(1747)  评论(0编辑  收藏  举报

导航