首先先把xml的节点读取出来
private XmlNode ReadXmlNodeRoot(String xml) { XmlNode xmlNodeRoot = null; if (!String.IsNullOrEmpty(xml)) { XmlReaderSettings xmlReaderSettings = new XmlReaderSettings(); xmlReaderSettings.IgnoreComments = true; XmlReader xmlReader = XmlReader.Create(new StringReader(xml), xmlReaderSettings); XmlDocument xmlDocument = new XmlDocument(); xmlDocument.Load(xmlReader); XmlNodeList xmlNodeList = xmlDocument.SelectNodes("root"); if (null != xmlNodeList && xmlNodeList.Count == 1) { xmlNodeRoot = xmlNodeList[0]; } } return xmlNodeRoot; }
现在要把xml的转化为数据实体,如果手动赋值会非常麻烦,如下
this.ModelData1=xmlNodeRoot["rootName1"].InnerText; this.ModelData2=xmlNodeRoot["rootName2"].InnerText; this.ModelData3=xmlNodeRoot["rootName3"].InnerText;
当节点多的时候,这样赋值会非常麻烦,而且必须知道xml中的所有节点名点,如果xml中少传一个节点,并且赋值是没有做判断,那么更会报异常,程序出错。
下面用发射来动态生成数据实体,就会非常简单
private void SetPropertyValue(XmlNode xmlNodeRoot) { if (null != xmlNodeRoot && xmlNodeRoot.ChildNodes.Count > 0) { PropertyInfo[] propertyInfos = this.GetType().GetProperties(); if (null != propertyInfos && propertyInfos.Length > 0) { Int32 propertyInfoCount = propertyInfos.Length; for (Int32 index = 0; index < propertyInfoCount; index++) { List<XmlElementExAttribute> dataattributelist= this.GetCallCenterAttribute<XmlElementExAttribute>(propertyInfos[index]); if (null != dataattributelist&& dataattributelist.Count > 0) { XmlNode xmlNode = xmlNodeRoot.SelectSingleNode(String.Format("/{0}/{1}", xmlNodeRoot.Name, dataattributelist[0].XmlElementName)); if (null != xmlNode) { propertyInfos[index].SetValue(this, xmlNode.InnerText, null); } } } } } } //根据propertyInfo来获取XmlElementExAttribute private List<T> GetCallCenterAttribute<T>(PropertyInfo propertyInfo) where T : class { List<T> customAttributeList = new List<T>(); if (null != propertyInfo) { Object[] customAttributes = propertyInfo.GetCustomAttributes(typeof(T), true); foreach (T singleCustomAttribute in customAttributes) { if (null != singleCustomAttribute) { customAttributeList.Add(singleCustomAttribute); } } } return customAttributeList; }
当用反射给数据实体赋值时,在定义实体时还要注意标注特性
private string pepolename; [XmlElementExAttribute("姓名", "xmlppepolename")] public string Pepolename { set { this.pepolename=value; } get { return this.pepolename; } }
可以看到上面属性中有一个XmlElementExAttribute的特性,此特性实际上是继承了反射基类Attribute,如下:
[AttributeUsage( AttributeTargets.Property , AllowMultiple = false )] public class XmlElementExAttribute : Attribute { #region Fields /// <summary> /// 描述 /// </summary> private String description; /// <summary> /// XML 元素名称 /// </summary> private String xmlElementName; #endregion #region Constructors /// <summary> /// PPTSCallCenterAttribute /// </summary> /// <param name="description">描述</param> /// <param name="typeName">类型名称</param> /// <param name="xmlElementName">XML元素名称</param> public XmlElementExAttribute( String description , String xmlElementName ) { this.description = description; this.xmlElementName = xmlElementName; } #endregion #region Properties /// <summary> /// 描述 /// </summary> public String Description { set { this.description = value; } get { return this.description; } } /// <summary> /// XML 元素名称 /// </summary> public String XmlElementName { set { this.xmlElementName = value; } get { return this.xmlElementName; } } #endregion }
如果要在赋值时做数据验证,还要添加一个特性,并且调用下面的方法
[VerifyString("姓名", false, "姓名验证失败")]
public class VerifyString : VerifyDataAttribute { public VerifyString( String description , Boolean isNull , String errorMessage ) : base( description , isNull , errorMessage ) { } public override Boolean VerifyData( Object verifyContent ) { #region if( null == verifyContent ) { return false; } Boolean isVerifySuccess = false; if( !base.IsNull ) { if( String.IsNullOrEmpty( verifyContent.ToString( ) ) ) { return false; } } isVerifySuccess = true; return isVerifySuccess; #endregion } }
如果要验证某个属性的正确性,类要继承于VerifyDataAttribute这个基类,具体怎样验证,就没有限制了
在验证时,调用下列方法
在给属性赋值时,加入下列方法
List<VerifyDataAttribute> verifyDataAttributeList = this.GetCallCenterAttribute<VerifyDataAttribute>(propertyInfos[index]); if (null != verifyDataAttributeList && verifyDataAttributeList.Count > 0) { foreach (VerifyDataAttribute verifyData in verifyDataAttributeList) { //注意,此VerifyData是验证特性中的重写方法,可在数据实体中定义 if (!(verifyData.VerifyData(propertyInfos[index].GetValue(this, null)))) { throw new Exception(verifyData.ErrorMessage); } } }