以对象的方式来访问xml数据表(三)
怎样以对象的方式来访问xml数据表?
在讲如何具体实现(二)中所说的专门用于访问xml文件的动态链接库之前,我们先来看看这个动态链接库具体要实现什么功能。
动态链接库IXmlDB.dll的功能:
1、对于不同的对象具有通用性。(简单地说就是在不修改内部代码的情况下,可以用不同的对象去映射不同的xml数据表)
由于数据保存在xml数据表里,所有数据都是以字符串的形式保存的,那么与之对应的对象里的属性就可以全部统一为string类型。
类与xml数据表映射的两个实例代码:
User类与其对应xml数据文件
class User
{
public string Id { get; set; }
public string Name { get; set; }
public string Password { get; set; }
public string IsAdmin { get; set; }
public string CreateTime { get; set; }
}
<?xml version="1.0" encoding="utf-8"?>
<Users>
<User>
<Id>1</Id>
<Name>forcheng</Name>
<Password>123456</Password>
<IsAdmin>True</IsAdmin>
<CreateTime>2016/01/14 16:08:00</CreateTime>
</User>
<User>
<Id>2</Id>
<Name>chuan</Name>
<Password>123456</Password>
<IsAdmin>False</IsAdmin>
<CreateTime>2016/01/15 11:23:00</CreateTime>
</User>
</Users>
Task类与其对应xml数据文件
class Task
{
public string Id { get; set; }
public string Name { get; set; }
public string CreateTime { get; set; }
public string Description { get; set; }
public string StartTime { get; set; }
public string EndTime { get; set; }
}
<?xml version="1.0" encoding="utf-8"?>
<Tasks>
<Task>
<Id>1</Id>
<Name>完成wpf桌面应用程序设计</Name>
<CreateTime>2016/01/14 16:08:00</CreateTime>
<Description>高效快速</Description>
<StartTime>2016/01/15 12:00:00</StartTime>
<EndTime>2016/01/18 12:00:00</EndTime>
</Task>
<Task>
<Id>2</Id>
<Name>买牙膏</Name>
<CreateTime>2016/01/15 16:08:00</CreateTime>
<Description>不要忘记了</Description>
<StartTime>2016/01/16 12:00:00</StartTime>
<EndTime>2016/01/16 14:00:00</EndTime>
</Task>
</Tasks>
2、对象和xml数据(XElement)的相互转换。(首先,从xml数据文件里面加载数据,需要转化为对相应的TEntity对象(泛型),然后保存在List<TEntity>列表里面,以提供对数据的操作,其次,是将List<TEntity>里面的数据转化为对应的XElement数据,然后添加保存到xml数据文件中)
3、需要提供一个构造函数或公有方法用于连接指定的xml数据文件。(需要给定一些参数,比如说xml文件所在的路径,xml文件的访问节点的名称(如"User")和根节点的名称(如"Users"))
4、提供一些公有方法用于用户操作数据。(比如说:添加数据、删除数据、查询数据、更改数据——这里的数据是以一个一个的对象形式存在的)
5、一些私有方法。(主要用于实现对象与XElement数据的转换,以及其他一些对数据合法性的验证)
在了解了动态链接库具体要实现什么功能之后,简单的谈一谈实现某几个功能的难点。
第一个难点:对于不同的对象具有通用性。怎样使得这个动态链接库能够在不改变源代码的情况下去操作具有不同属性的类?本来最初我是打算使用动态编译类(需要使用程序集和反射的知识)来实现,但是后面发现使用动态编译类不能满足这个要求或即使实现了对性能的牺牲太大了。于是乎就舍弃了动态类这个想法。最终还是从Entity Framework的操作数据库接口DbSet那里获得的灵感,使用泛型类。泛型恰好满足了不同对象这一点要求。最终问题成功解决。
第二个难点:对象和xml数据(XElement)的相互转换。由于对象里面的属性名称是不确定的(至少对于动态链接库里面那个访问数据文件的对象来说)。这就造成了一个很大的问题:如何在一个已经封装好了的对象(也就是动态链接库里面的那个泛型类)里面的去操作一个未知属性的对象的属性?因为对象和XElement之间进行数据的传递,必须要对对象的属性进行操作。为了解决这个问题,我查了相应的资料,发现了反射能够成功解决这个问题。首先,实例化泛型类的时候,可以获取到TEntity对象的属性的名称(可以用一个数组临时保存),然后再通过泛型直接对TEntity对象的属性的值进行获取或赋值,这样就可以实现对象和xml数据的相互传递了。
最后,附上IXmlDB4.1.0.dll的源代码和一个简单的演示实例(以对象的方式来访问xml数据表)。
这是我经过反复修改和提高之后产生的(大家可以从它的版本号看出)。 感兴趣的可以深入研究一下源代码(其中有的地方用了取巧的方法^_^),若只是想用一下,则可以直接编译成.dll文件即可使用。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions; namespace IXmlDB
{ public class XmlDbSet<TEntity> where TEntity : class, new()
{ //构造函数
public XmlDbSet(string path = "XmlDb.xml", string nodeName = "Node", string rootName = "Root")
{
defaultProperty = "Id";
if (Connect(path, nodeName, rootName))
{
//链接成功,载入数据
classList = new List<TEntity>();
foreach (var item in AllNodes)
{
classList.Add(XElementToClass(item));
}
}
else
{
throw new Exception("连接数据文件失败!");
}
} #region 私有字段
private string xmlFilePath;
private string[] xmlProperties;
private string nodeName;
private string defaultProperty;
private XElement xmlRoot;
private List<TEntity> classList; #endregion #region 私有属性
//获取新的Id
private int NewId
{
get
{
if (classList.Count() > )
{
var lastNode = classList.Select(m => Convert.ToInt32(ReflectionGetProperty(m, defaultProperty)));
return (lastNode.Max() + );
}
else
{
return ;
}
}
} //获取所有子节点
private IEnumerable<XElement> AllNodes
{
get
{
return xmlRoot.Elements(nodeName);
}
} #endregion #region 公有方法 //添加单个实例
public TEntity Add(TEntity entity)
{
if(ReflectionGetProperty(entity,defaultProperty) == "")
{
ReflectionSetProperty(entity, defaultProperty, NewId.ToString());
classList.Add(entity);
}
return entity;
} //添加多个实例
public IEnumerable<TEntity> AddRange(IEnumerable<TEntity> entities)
{
int id = NewId;
foreach (var entity in entities)
{
if (ReflectionGetProperty(entity, defaultProperty) == "")
{
ReflectionSetProperty(entity, defaultProperty, id.ToString());
classList.Add(entity);
id++;
}
}
return entities;
} //确定序列中所有元素是否满足条件
public bool All(Func<TEntity, bool> predicate)
{
return classList.All(predicate);
} //确定序列中是否包含任何元素
public bool Any()
{
return classList.Any();
} //确定序列中任何元素是否满足条件
public bool Any(Func<TEntity, bool> predicate)
{
return classList.Any(predicate);
} //从序列中移除所有元素
public void Clear()
{
classList.Clear();
} //链接两个序列
public IEnumerable<TEntity> Concat(IEnumerable<TEntity> second)
{
return classList.Concat(second);
} //获取序列中包含的元素数
public int Count()
{
return classList.Count;
} //返回一个数字,表示在指定序列中满足条件的元素的数量
public int Count(Func<TEntity, bool> predicate)
{
return classList.Count(predicate);
} //确定指定元素是否在序列中
public bool Contains(TEntity item)
{
return classList.Contains(item);
} //返回序列中指定索引出的元素
public TEntity ElementAt(int index)
{
return classList.ElementAt(index);
} //返回序列中指定索引出的元素,如果超出指定范围,则返回默认值(null)
public TEntity ElementAtOrDefault(int index)
{
return classList.ElementAtOrDefault(index);
} //确定序列中是否包含与指定谓词所定义的条件相匹配的元素
public bool Exists(Predicate<TEntity> match)
{
return classList.Exists(match);
} //通过使用默认比较器对值进行比较生成两个序列的差集
public IEnumerable<TEntity> Equals(IEnumerable<TEntity> second)
{
return classList.Except(second);
} //返回序列中满足指定条件的第一个元素;若序列中不包含元素,则返回默认值
public TEntity FirstOrDefault(Func<TEntity, bool> predicate)
{
return classList.FirstOrDefault(predicate);
} //搜索与指定谓词相匹配的元素,并返回第一个匹配的元素
public TEntity Find(Predicate<TEntity> match)
{
return classList.Find(match);
} //搜索与指定谓词相匹配的所有元素
public IEnumerable<TEntity> FindAll(Predicate<TEntity> match)
{
return classList.FindAll(match);
} //搜索与指定谓词相匹配的元素,并返回第一个匹配的元素的从零开始的索引
public int FindIndex(Predicate<TEntity> match)
{
return classList.FindIndex(match);
} //搜索与指定谓词相匹配的元素,并返回最后一个匹配的元素
public TEntity FindLast(Predicate<TEntity> match)
{
return classList.FindLast(match);
} //搜索与指定谓词相匹配的元素,并返回最后一个一个匹配的元素的从零开始的索引
public int FindLastIndex(Predicate<TEntity> match)
{
return classList.FindLastIndex(match);
} //返回序列中的第一个元素
public TEntity First()
{
return classList.First();
} //返回序列中满足指定条件的第一个元素
public TEntity First(Func<TEntity, bool> predicate)
{
return classList.First(predicate);
} //返回序列中的第一个元素;若序列中不包含元素,则返回默认值
public TEntity FirstOrDefault()
{
return classList.FirstOrDefault();
} //对序列中的每一个元素执行指定操作
public void ForEach(Action<TEntity> action)
{
classList.ForEach(action);
} //搜索指定对象,并返回序列中第一个匹配项的从零开始的索引
public int IndexOf(TEntity item)
{
return classList.IndexOf(item);
} //将元素插入到序列中指定的索引处(索引从0开始)
public void Insert(int index, TEntity item)
{
if (ReflectionGetProperty(item, defaultProperty) == "")
{
ReflectionSetProperty(item, defaultProperty, NewId.ToString());
}
classList.Insert(index,item);
} //将集合中的元素插入到序列中指定的索引处(索引从0开始)
public void InsertRange(int index, IEnumerable<TEntity> collection)
{
int id = NewId;
foreach (var item in collection)
{
if (ReflectionGetProperty(item, defaultProperty) == "")
{
ReflectionSetProperty(item, defaultProperty, id.ToString());
id++;
}
}
classList.InsertRange(index, collection);
} //返回序列中的最后一个元素
public TEntity Last()
{
return classList.Last();
} //返回序列中满足指定条件的最后一个元素
public TEntity Last(Func<TEntity, bool> predicate)
{
return classList.Last(predicate);
} //搜索指定对象,并返回序列中第一个匹配项的从零开始的索引
public int LastIndexOf(TEntity item)
{
return classList.LastIndexOf(item);
} //返回序列中的最后一个元素;若序列中不包含元素,则返回默认值
public TEntity LastOrDefault()
{
return classList.LastOrDefault();
} //调用泛型序列的每一个元素上的转换函数并返回最大结果值
public string Max(Func<TEntity,string> selector)
{
return classList.Max(selector);
} //调用泛型序列的每一个元素上的转换函数并返回最小结果值
public string Min(Func<TEntity, string> selector)
{
return classList.Min(selector);
} //根据键按升序对序列的元素排序
public void OrderBy(Func<TEntity, string> keySelector)
{
classList = classList.OrderBy(keySelector).ToList();
} //根据键按降序对序列的元素排序
public void OrderByDescending(Func<TEntity, string> keySelector)
{
classList = classList.OrderByDescending(keySelector).ToList();
} //将整个序列中元素顺序逆转
public void Reverse()
{
classList.Reverse();
} //从classLIst中移除特定对象的第一个匹配项
public TEntity Remove(TEntity entity)
{
classList.Remove(entity);
return entity;
} //从classLIst中移除一组对象的第一个匹配项
public IEnumerable<TEntity> RemoveRange(IEnumerable<TEntity> entities)
{
foreach(var entity in entities)
{
classList.Remove(entity);
}
return entities;
} //删除指定谓词所定义的条件匹配的所有元素
public int RemoveAll(Predicate<TEntity> match)
{
return classList.RemoveAll(match);
} //删除指定索引出的元素
public void RemoveAt(int index)
{
classList.RemoveAt(index);
} //保存更改(返回值:表示重写以及删除的实例个数)
public void SaveChanges()
{
xmlRoot.RemoveAll();
foreach (var item in classList)
{
xmlRoot.Add(ClassToXElement(item));
};
xmlRoot.Save(xmlFilePath);
} //保存更改(返回值:表示重写的实例个数)
public int SaveChanges(TEntity entity)
{
if(entity != null)
{
if(ClassModToXElement(entity))
{
xmlRoot.Save(xmlFilePath);
return ;
}
else
{
return ;
}
}
else
{
return ;
}
} //保存更改(返回值:表示重写实例个数)
public int SaveChanges(IEnumerable<TEntity> entities)
{
if (entities != null)
{
int count = ;
foreach(var entity in entities)
{
if (ClassModToXElement(entity))
{
count++;
}
}
if(count > )
{
xmlRoot.Save(xmlFilePath);
}
return count;
}
else
{
return ;
}
} //返回序列中唯一满足条件的元素;如果这类元素不存在,则返回默认值;如果存在多个元素满足条件,此方法将引发异常
public TEntity SingleOrDefault(Func<TEntity, bool> predicate)
{
return classList.SingleOrDefault(predicate);
} //将序列中的每个元素投影到新表中
public IEnumerable<TResult> Select<TResult>(Func<TEntity, TResult> predicate)
{
return classList.Select(predicate);
} //将序列中的每个元素投影到IEnumerable<out T> 并将结果序列合并为一个序列
public IEnumerable<TResult> SelectMany<TResult>(Func<TEntity, IEnumerable<TResult>> selector)
{
return classList.SelectMany(selector);
} //跳过序列中指定数量的元素,然后返回剩余元素
public IEnumerable<TEntity> Skip(int index)
{
return classList.Skip(index);
} //只要满足指定的条件,就跳过序列中的元素,然后返回剩余元素
public IEnumerable<TEntity> SkipWhile(Func<TEntity, bool> predicate)
{
return classList.SkipWhile(predicate);
} //计算int值序列的和,这些值是通过对输入序列中的每一个元素调用转换函数得到的
public int Sum(Func<TEntity, int> selector)
{
return classList.Sum(selector);
}
public long Sum(Func<TEntity, long> selector)
{
return classList.Sum(selector);
}
public float Sum(Func<TEntity, float> selector)
{
return classList.Sum(selector);
}
public double Sum(Func<TEntity, double> selector)
{
return classList.Sum(selector);
}
public decimal Sum(Func<TEntity, decimal> selector)
{
return classList.Sum(selector);
} //从序列的开头返回指定数量的连续元素
public IEnumerable<TEntity> Take(int index)
{
return classList.Take(index);
} //只要满足指定条件,就会返回序列中的元素
public IEnumerable<TEntity> TakeWhile(Func<TEntity, bool> predicate)
{
return classList.TakeWhile(predicate);
} //确定是否序列中每一个元素都与指定的谓词所定义的条件相匹配
public bool TrueForAll(Predicate<TEntity> match)
{
return classList.TrueForAll(match);
} //通过使用默认的相等比较器生成两个序列的并集
public IEnumerable<TEntity> Union(IEnumerable<TEntity> second)
{
return classList.Union(second);
} //基于谓此筛选值序列
public IEnumerable<TEntity> Where(Func<TEntity, bool> predicate)
{
return classList.Where(predicate);
} #endregion #region 私有方法
//连接数据文件
private bool Connect(string path, string nodeName, string rootName)
{
try
{
//检查参数是否为null或为空字符串
if (string.IsNullOrWhiteSpace(path) || string.IsNullOrWhiteSpace(nodeName) || string.IsNullOrWhiteSpace(rootName))
{
return false;
}
//匹配xml文件路径
if (path.IndexOf("\\") == -)
{
path = Environment.CurrentDirectory + "\\" + path;
}
if (!Regex.IsMatch(path, @"^(?<fpath>([a-zA-Z]:\\)([\s\.\-\w]+\\)*)(?<fname>[\w]+.[\w]+)") || path.Length < || path.Substring(path.Length - ).ToLower() != ".xml")
{
return false;
}
//检查属性是否合法
TEntity objClass = new TEntity();
PropertyInfo[] infos = objClass.GetType().GetProperties();
if (infos.Length == || infos.Count(m => m.Name == defaultProperty) == )
{
return false;
}
xmlProperties = new string[infos.Length];
int i = ;
foreach (var info in infos)
{
if (string.IsNullOrWhiteSpace(info.Name) || infos.Count(m => m.Name == info.Name) > )
{
return false;
}
else
{
xmlProperties[i] = info.Name;
i++;
}
}
this.nodeName = nodeName;
xmlFilePath = path; //判断xml文件是否存在,若不存在则创建
if (path.LastIndexOf("\\") > )
{
path = path.Substring(, path.LastIndexOf("\\"));
}
else
{
path = "";
}
string quote = "\"";
if (path != "" && !Directory.Exists(path))
{
Directory.CreateDirectory(path);
var xmlFile = new StreamWriter(xmlFilePath); xmlFile.WriteLine("<?xml version=" + quote + "1.0" + quote + " encoding=" + quote + "utf-8" + quote + "?>");
xmlFile.WriteLine("<" + rootName + ">");
xmlFile.WriteLine("</" + rootName + ">");
xmlFile.Close();
}
else
{
if (!File.Exists(xmlFilePath))
{
var xmlFile = new StreamWriter(xmlFilePath);
xmlFile.WriteLine("<?xml version=" + quote + "1.0" + quote + " encoding=" + quote + "utf-8" + quote + "?>");
xmlFile.WriteLine("<" + rootName + ">");
xmlFile.WriteLine("</" + rootName + ">");
xmlFile.Close();
}
}
xmlRoot = XElement.Load(xmlFilePath);//载入数据文件 //自检数据文件
if (NodesPropertiesIsValid())
{
return true;
}
else
{
throw new Exception("数据文件不完整或损坏!");
}
}
catch (Exception e)
{
throw e;
}
} //检查节点属性是否合法
private bool NodePropertiesIsValid(XElement targetNode)
{
try
{
if (targetNode.Name.ToString() != nodeName)
{
return false;
}
for (int i = ; i < xmlProperties.Length; i++)
{
if (targetNode.Element(xmlProperties[i]) == null)
{
return false;
}
}
return true;
}
catch
{
return false;
}
} //检查整个xml文件属性和Id是否合法(加载自检)
private bool NodesPropertiesIsValid()
{
try
{
if(AllNodes.Count() == )
{
return true;
}
var strs = AllNodes.Select(m => m.Element(defaultProperty).Value).Distinct();
if (strs.Count() != AllNodes.Count() || AllNodes.Count(m => !NodePropertiesIsValid(m)) > )
{
return false;
}
else
{
return true;
} }
catch
{
return false;
}
} //将xml元素转化为对应对象(新实例)
private TEntity XElementToClass(XElement targetNode)
{
if (targetNode == null)
{
return null;
}
else
{
TEntity objClass = new TEntity();
for (int i = ; i < xmlProperties.Length; i++)
{
ReflectionSetProperty(objClass, xmlProperties[i], targetNode.Element(xmlProperties[i]).Value);
}
return objClass;
} } //将对象转化为对应的xml元素新实例)
private XElement ClassToXElement(TEntity objClass)
{
if (objClass == null)
{
return null;
}
else
{
XElement newNode = new XElement(nodeName);
for (int i = ; i < xmlProperties.Length; i++)
{
newNode.Add(new XElement(xmlProperties[i], ReflectionGetProperty(objClass, xmlProperties[i])));
}
return newNode;
}
} //将对象的值传给对应的xml元素,或直接添加
//private void ClassSaveToXElement(TEntity objClass)
//{
// string id = ReflectionGetProperty(objClass, defaultProperty);
// var targetNode = AllNodes.SingleOrDefault(m => m.Element(defaultProperty).Value == id);
// if (targetNode != null)
// {
// for (int i = 0; i < xmlProperties.Length; i++)
// {
// targetNode.Element(xmlProperties[i]).Value = ReflectionGetProperty(objClass, xmlProperties[i]);
// }
// }
// else
// {
// xmlRoot.Add(ClassToXElement(objClass));
// }
//} //将对象的值传给对应的xml元素 private bool ClassModToXElement(TEntity objClass)
{
string id = ReflectionGetProperty(objClass, defaultProperty);
var targetNode = AllNodes.SingleOrDefault(m => m.Element(defaultProperty).Value == id);
if (targetNode != null)
{
for (int i = ; i < xmlProperties.Length; i++)
{
targetNode.Element(xmlProperties[i]).Value = ReflectionGetProperty(objClass, xmlProperties[i]);
}
return true;
}
else
{
return false;
}
} ////动态编译类
//private Assembly NewAssembly()
//{
// //创建编译器实例。
// CSharpCodeProvider provider = new CSharpCodeProvider();
// //设置编译参数。
// CompilerParameters paras = new CompilerParameters();
// paras.GenerateExecutable = false;
// paras.GenerateInMemory = true; // //创建动态代码。
// StringBuilder classSource = new StringBuilder();
// classSource.Append("public class DynamicClass \n");
// classSource.Append("{\n"); // //创建属性。
// for (int i = 0; i < xmlProperties.Length; i++)
// {
// classSource.Append(" public string " + xmlProperties[i] + " { get; set; } \n");
// } // classSource.Append("}"); // System.Diagnostics.Debug.WriteLine(classSource.ToString()); // //编译代码。
// CompilerResults result = provider.CompileAssemblyFromSource(paras, classSource.ToString()); // //获取编译后的程序集。
// Assembly assembly = result.CompiledAssembly; // return assembly;
//} //反射设置动态类的实例对象的指定的属性值 private void ReflectionSetProperty(TEntity objClass, string propertyName, string value)
{
objClass.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance).SetValue(objClass, value ?? "", null);
} //反射返回动态类的实例对象的指定的属性值
private string ReflectionGetProperty(TEntity objClass, string propertyName)
{
try
{
return objClass.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance).GetValue(objClass, null).ToString();
}
catch
{
return "";
}
} #endregion
}
}
实例演示代码——以对象的方式来访问xml数据表:
using System;
using IXmlDB; namespace ConsoleApplication2
{
//操作xml数据库的类
class DbSet
{
public XmlDbSet<User> Users { get; set; } = new XmlDbSet<User>("User.xml", "User", "Users");//连接User.xml数据文件,若不存在,会自动创建
public XmlDbSet<Task> Tasks { get; set; } = new XmlDbSet<Task>("Task.xml", "Task", "Tasks");//连接Task.xml数据文件
}
//用户类
class User
{
public string Id { get; set; } //为了数据表的规范,Id属性是每个xml数据表的必须有的,并且它的值是动态链接库自动添加上去的(可以理解为具有自加性),用户不用给它赋值
public string Name { get; set; }
public string Password { get; set; }
public string IsAdmin { get; set; }
public string CreateTime { get; set; }
}
//任务类
class Task
{
public string Id { get; set; }
public string Name { get; set; }
public string CreateTime { get; set; }
public string Description { get; set; }
public string StartTime { get; set; }
public string EndTime { get; set; }
} class Program
{
static void Main(string[] args)
{
DbSet entity = new DbSet();//创建访问数据库的实例 User u = new User();
u.Name = "forcheng";
u.Password = "";
u.IsAdmin = true.ToString();
u.CreateTime = DateTime.Now.ToString(); Task task = new Task();
task.Name = "买牙膏";
task.CreateTime = DateTime.Now.ToString();
task.Description = "不要忘记了";
task.StartTime = DateTime.Now.ToString();
task.EndTime = ""; //添加对象
entity.Users.Add(u);
entity.Tasks.Add(task); //输出已添加对象的个数
Console.WriteLine(entity.Users.Count());
Console.WriteLine(entity.Tasks.Count()); var user = entity.Users.FirstOrDefault();//获取第一个
if(user != null)
{
Console.WriteLine(user.Name);
Console.WriteLine(user.Password);
Console.WriteLine(user.IsAdmin);
Console.WriteLine(user.CreateTime);
} entity.Users.RemoveAt();//移除第一个对象
var user1 = entity.Users.FirstOrDefault();//获取第一个
if (user1 != null)
{
Console.WriteLine(user1.Name);
Console.WriteLine(user1.Password);
Console.WriteLine(user1.IsAdmin);
Console.WriteLine(user1.CreateTime);
} entity.Users.SaveChanges();//把更改保存到xml文件中
entity.Tasks.SaveChanges();//把更改保存到xml文件中 Console.ReadKey();
}
}
}
欢迎大家借鉴学习,以对象的方式来访问xml数据表的专题到这里就结束了!!!
接下来,我可能会讲我比较喜爱的命令行与脚本专题系列,感兴趣的敬请期待哦。
<我的博客主页>:http://www.cnblogs.com/forcheng/
以对象的方式来访问xml数据表(三)的更多相关文章
- 以对象的方式来访问xml数据表(二)
为什么要以对象的方式来访问xml数据表? 还记得,自己是在一次完成师兄布置的任务时接触到了xml,那时候需要用xml来作为数据文件,保存一个简单的图书管理系统的数据.于是就知道了,可以用xml文件来保 ...
- 以对象的方式来访问xml数据表(一)
所有实例代码都是以C#演示—— 在将如何以对象的方式来访问xml数据表之前,我们先来谈谈如何用xml文件作为数据库吧! 平时在开发一些小的应用的时候,需要一个数据库,这个时候虽然可以用SQL serv ...
- Ajax跨域访问XML数据的另一种方式——使用YQL查询语句
XML数据默认是不能在客户端通过Ajax跨域请求读取的,一般的做法是在服务器上写一个简单的代理程序,将远程XML的数据先读到本地服务器,然后客户端再从本地服务器通过Ajax来请求.由于我们不能对数据源 ...
- wcf序列化大对象时报错:读取 XML 数据时,超出最大
错误为: 访问服务异常:格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出 错: request.InnerException 消息是“反序 ...
- 使用Entity Framework通过code first方式创建数据库和数据表
开发环境 WIN10 Entity Framework6.0 MVC5.0 开发工具 VS2015 SqlServer2012 1.创建上下文Context继承DbContext,并创建其他的业 ...
- SpringMVC06以对象的方式获取前台的数据
========创建需要的两个实体类================ public class School { private String sName; private String addres ...
- 使用JavaScript访问XML数据
在本篇文章中,我们将讲述如何在IE中使用ActiveX功能来访问并解析XML文档,由此允许网络冲浪者操纵它们.这一网页将传入并运行脚本的初始化.你一定确保order.xml文档与jsxml.html在 ...
- LinkServer--访问远程数据表三种方式
在TSQL中访问远程数据库有三种方式:1.OPENROWSET2.OPENDATASOURCE3.LinkServer 在使用openrowset/opendatasource前搜先要启用Ad Hoc ...
- hibernate中.hbm.xml和注解方式自动生成数据表的简单实例(由新手小白编写,仅适用新手小白)
绝逼新手小白,so 请大神指点! 如果真的错的太多,错的太离谱,错的误导了其他小伙伴,还望大神请勿喷,大神请担待,大神请高抬贵嘴......谢谢. 好了,正题 刚接触ssh,今天在搞使用.hbm.xm ...
随机推荐
- “You must not call setTag() on a view Glide is targeting” 解决
报错原因大致是因为Glide加载的iamgeView调用了setTag()方法导致的错误, 因为Glide已经默认为ImageView设置的Tag. 解决办法:自定义一个Application,在里面 ...
- 一种线程安全的handle
对象引用的正确性在多线程环境下是一个复杂的问题,请参考,处理由引用计数引起的泄漏.简单来说,我们应该尽量减少使用强引用,否则将有可能产生[处理由引用计数引起的泄漏]一文中描述的难以察觉的内存泄漏问题. ...
- saiku源代码安装
以前的文章介绍了如何直接安装saiku,http://www.cnblogs.com/liqiu/p/5183894.html .这里面偷懒没有源代码编译,不过这几天也就这么用了. 最近随着使用的深入 ...
- asp.net添加验证码
1.新建一个aspx页面生成验证码图像 using System; using System.Data; using System.Configuration; using System.Collec ...
- Qt5 从头学(2)--手动构建HelloWold
在上一篇随笔中已经搭建好了Qt5的的开发环境,并且通过Qt Creator自动构建了一个视窗程序.在这篇文章中我们将手动编写一个HelloWold程序,简单了解一下Qt的构建过程.这里我们不会涉及到Q ...
- MyBatis知多少(8)关系型数据库
MyBatis的存在就是为了简化对关系数据库的访问.数据库的确非常复杂,要正确地使用它们需要做很多的工作.数据库负责管理数据和修改数据.我们使用数据库而不简简单单地使用一个 平板文件的原因就在于数据库 ...
- 导出excel和PDF小结 vba
最近接触了一个关于Access工具的项目,所以整理下需要使用的方法. 功能要求简介: 1.将数据表中的数据导出到excel和PDF 2.并根据某个字段名称分sheet输出. 3.无模板方式 方案简介: ...
- table相关的API
void lua_getglobal (lua_State *L, const char *name);获取lua全局变量,将lua的全局变量global name压栈.堆栈+1 void lua_s ...
- 如何在shell中打印出带颜色的字符?
先看如下的效果: 方法: 先看如下的脚本sh3.sh: #!/bin/bash echo "peng" echo "$(color bold yellow) ------ ...
- Hadoop入门进阶课程2--Hadoop2.X 64位编译
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,博主为石山园,博客地址为 http://www.cnblogs.com/shishanyuan ...