为什么要以对象的方式来访问xml数据表?

  还记得,自己是在一次完成师兄布置的任务时接触到了xml,那时候需要用xml来作为数据文件,保存一个简单的图书管理系统的数据。于是就知道了,可以用xml文件来保存数据(而且比用简单的文本文件保存数据规范的多,在访问与读取数据上面都十分方便),就这样使用xml的征程开始了。

  自己做的第一个WPF桌面应用程序——备忘录,就是用xml文件作为数据库。而且那个时候考虑到以后可能会经常使用到xml文件作为数据库,于是乎就写了一个专门用于访问xml文件的动态链接库,这样不仅可以提高代码的重用性(用功一次,获益无穷),而且还提高了软件后期的维护效率(由于规范),动态链接库实现的基本功能:将连接数据文件的过程和检查规范全封装在一个方法里面(而数据表的属性是通过数组传参传递),将对数据的增、删、查、改也全部封装成各种方法,还封装了一些属性等等。但此时的自己还没有面向对象开发的思维,最终在开发时还是以传统的方式去访问的xml数据表(Element(value))。

  这是我第一个版本的访问xml的动态链接库源码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.IO;
using System.Text.RegularExpressions; namespace XmlIDataBase
{
public class XmlDataBase
{
#region 私有字段
private string xmlFilePath;
private string[] xmlProperties;
private string noteName;
#endregion #region 公有字段
public XElement Notes;
#endregion #region 公有方法
//连接数据文件
public bool Connect(string path_, string noteName_, params string[] properties)
{
try
{
//匹配xml文件路径
if (!Regex.IsMatch(path_, @"^(?<fpath>([a-zA-Z]:\\)([\s\.\-\w]+\\)*)(?<fname>[\w]+.[\w]+)") || noteName_ == "" || path_.Length < || path_.Substring(path_.Length - ).ToLower() != "xml")
{
return false;
}
noteName = noteName_;//记录每条记录的名称
xmlFilePath = path_;//记录文件路径 if (path_.LastIndexOf("\\") > )
{
path_ = path_.Substring(, path_.LastIndexOf("\\"));
}
else
{
path_ = "";
} if (path_ != "" && !Directory.Exists(path_))
{
Directory.CreateDirectory(path_);
var xmlFile = new StreamWriter(xmlFilePath);
xmlFile.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
xmlFile.WriteLine("<" + noteName + "s>");
xmlFile.WriteLine("</" + noteName + "s>");
xmlFile.Close();
}
else
{
if (!File.Exists(xmlFilePath))
{
var xmlFile = new StreamWriter(xmlFilePath);
xmlFile.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
xmlFile.WriteLine("<" + noteName + "s>");
xmlFile.WriteLine("</" + noteName + "s>");
xmlFile.Close();
}
} Notes = XElement.Load(xmlFilePath);
xmlProperties = new string[properties.Length];
xmlProperties = properties;//记录每条记录的属性
return true;
}
catch (Exception e)
{
throw e;
//return false;
}
} //保存数据文件
public bool SaveChanged()
{
try
{
Notes.Save(xmlFilePath);
return true;
}
catch (Exception e)
{
throw e;
//return false;
}
} //添加纪录:添加到末尾(方法一)
public bool AddNote(params string[] propertyValues)
{
try
{
if (propertyValues.Length == xmlProperties.Length)
{
if (Notes.Elements(noteName).Count() > )
{
int newNo;
var lastNote = from Note in Notes.Elements() select Convert.ToInt32(Note.Attribute("No").Value);
newNo = lastNote.Max() + ;
Notes.LastNode.AddAfterSelf(noteName, new XAttribute("No", newNo));
for (int i = ; i < xmlProperties.Length; i++)
{
if (i == )
{
Notes.Elements().Last().AddFirst(new XElement(xmlProperties[i], propertyValues[i]));
}
else
{
Notes.Elements().Last().LastNode.AddAfterSelf(new XElement(xmlProperties[i], propertyValues[i]));
}
}
}
else
{
Notes.AddFirst(new XElement(noteName, new XAttribute("No", )));
for (int i = ; i < xmlProperties.Length; i++)
{
if (i == )
{
Notes.Element(noteName).AddFirst(new XElement(xmlProperties[i], propertyValues[i]));
}
else
{
Notes.Element(noteName).LastNode.AddAfterSelf(new XElement(xmlProperties[i], propertyValues[i]));
}
}
}
return true;
}
else
{
return false;
}
}
catch (Exception e)
{
throw e;
//return false;
} } //添加记录:添加到末尾(方法二)
public bool AddNote(XElement newNote)
{
try
{
if (newNote.Elements().Count() == xmlProperties.Length)
{
if (Notes.Elements(noteName).Count() > )
{
int newNo;
var lastNote = from Note in Notes.Elements() select Convert.ToInt32(Note.Attribute("No").Value);
newNo = lastNote.Max() + ;
if(newNote.Attribute("No") == null)
{
newNote.Add(new XAttribute("No", newNo));
}
else
{
newNote.Attribute("No").Value = newNo.ToString();
}
Notes.Elements().Last().AddAfterSelf(newNote);
}
else
{
if (newNote.Attribute("No") == null)
{
newNote.Add(new XAttribute("No", ));
}
else
{
newNote.Attribute("No").Value = "";
}
Notes.AddFirst(newNote);
}
return true;
}
else
{
return false;
}
}
catch (Exception e)
{
throw e;
//return false;
}
} //添加记录:添加到开头
public bool AddFistNote(XElement newNote)
{
try
{
if (newNote.Elements().Count() == xmlProperties.Length)
{
if (Notes.Elements(noteName).Count() > )
{
int newNo;
var lastNote = from Note in Notes.Elements() select Convert.ToInt32(Note.Attribute("No").Value);
newNo = lastNote.Max() + ;
if (newNote.Attribute("No") == null)
{
newNote.Add(new XAttribute("No", newNo));
}
else
{
newNote.Attribute("No").Value = newNo.ToString();
}
Notes.AddFirst(newNote);
}
else
{
if (newNote.Attribute("No") == null)
{
newNote.Add(new XAttribute("No", ));
}
else
{
newNote.Attribute("No").Value = "";
}
Notes.AddFirst(newNote);
}
return true;
}
else
{
return false;
}
}
catch (Exception e)
{
throw e;
//return false;
}
} //删除记录(单一索引)
public bool DeletNote(string no = "", params string[] propertyValues)
{
try
{
bool okFlag = false;
if (propertyValues.Length > xmlProperties.Length)
{
return false;
}
else
{
if (no == "") //按属性值相等删除
{
for (int i = ; i < propertyValues.Length; i++)
{
if (propertyValues[i] == "") continue;
if (Notes.Elements(noteName).Count() == ) return false;//数据文件内容为空
var proNotes = Notes.Elements(noteName).Elements(xmlProperties[i]).Where(m => m.Value == propertyValues[i]);
foreach (var item in proNotes)
{
item.Parent.Remove();
okFlag = true;
}
}
}
else //按编号相等删除
{
if (Notes.Elements(noteName).Count() == ) return false;//数据文件内容为空
var proNote = Notes.Elements(noteName).SingleOrDefault(m => m.Attribute("No").Value == no);
if (proNote != null)
{
proNote.Remove();
okFlag = true;
}
}
return okFlag;
}
}
catch (Exception e)
{
throw e;
//return false;
}
} //修改记录(编号索引:方法一)
public bool ModifyNote(string no, params string[] propertyValues)
{
try
{
if (no == "" || propertyValues.Length != xmlProperties.Length)
{
return false;
}
bool okFlag = false;
if (Notes.Elements(noteName).Count() == ) return false;//数据文件内容为空
var proNote = Notes.Elements(noteName).Attributes("No").SingleOrDefault(m => m.Value == no);
if (proNote != null)
{
var proSubNotes = proNote.Parent.Elements();
int i = ;
foreach (var item in proSubNotes)
{
item.Value = propertyValues[i++];
}
okFlag = true;
}
return okFlag;
}
catch (Exception e)
{
throw e;
//return false;
}
} //修改记录(编号索引:方法二用一个新的节点(No值不变)替代)
public bool ModifyNote(string no, XElement noteModified)
{
try
{
if (no == "" || noteModified.Elements().Count() != xmlProperties.Length)
{
return false;
}
bool okFlag = false;
if (Notes.Elements(noteName).Count() == ) return false;//数据文件内容为空
var proNote = Notes.Elements(noteName).Attributes("No").SingleOrDefault(m => m.Value == no);
if (proNote != null)
{
proNote.Parent.ReplaceWith(noteModified);
}
return okFlag; }
catch (Exception e)
{
throw e;
//return false;
}
} //查询记录(单一索引)
public IEnumerable<XElement> QueryNote(string no = "", params string[] propertyValues)
{
IEnumerable<XElement> result = null;
try
{
if (no == "" && propertyValues.Length == )//返回所有数据
{
return Notes.Elements(noteName);
}
if (no == "" && propertyValues.Length != )
{
for (int i = ; i < propertyValues.Length; i++)
{
if (propertyValues[i] == "") continue;
if (Notes.Elements(noteName).Count() == ) return result;//数据文件内容为空
var proNotes = Notes.Elements(noteName).Elements(xmlProperties[i]).Where(m => m.Value == propertyValues[i]);
return proNotes;
}
}
else
{
if (Notes.Elements(noteName).Count() == ) return result;//数据文件内容为空
var proNote = Notes.Elements(noteName).Attributes("No").SingleOrDefault(m => m.Value == no);
if (proNote != null)
{
result = new XElement[] { proNote.Parent };
}
} return result; }
catch (Exception e)
{
throw e;
//return false;
} } //获取记录的条数
public int Count()
{
try
{
return Notes.Elements(noteName).Count();
}
catch (Exception e)
{
throw e;
//return false;
}
} //获取所有记录
public IEnumerable<XElement> AllNotes()
{
try
{
return Notes.Elements(noteName);
}
catch (Exception e)
{
throw e;
//return false;
}
} //获取最后一条记录的No
public int GetLastNoteNo()
{
try
{
if (Notes.Elements(noteName).Count() > )
return (from Note in Notes.Elements(noteName) select Convert.ToInt32(Note.Attribute("No").Value)).Max();
else
return ;
}
catch (Exception e)
{
throw e;
//return false;
}
}
#endregion
}
}

  后面自己又用xml文件作为数据库开发了一个WPF桌面应用程序和一个小型的网站,此时的动态链接库还没有什么大的改进,只是对其中的代码进行了一些优化。直到那一天,我在用ASP.NET MVC开发工作室的门户网站(此时不再是用xml文件作为数据库,而是用的SQL Sever),涉及到对网站后台数据库的访问时,我发现了Entity Framework访问数据库的方便简洁之处,首先直接在Model里面写一个能够映射一张数据表的类(一般只需包含对应的属性即可),然后使用数据库上下文接口DbContext来轻轻松松访问数据库。先看看代码:

  Model里面的User类:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web; namespace Test.Models
{
public class User
{
[Required]
public Int32 Id { get; set; } [Required]
[DisplayName("名字")]
public String Name { get; set; } [Required]
[DisplayName("用户名")]
public String Account { get; set; } [Required]
[DisplayName("密码")]
public String Password { get; set; } //创建时间
[Required]
public DateTime CreateTime { get; set; } //标识是否为管理员
[Required]
public Boolean IsAdmin { get; set; } }
}

  继承了DbContext接口的类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity; namespace Test.Models
{
public class WS_WebAppContext : DbContext
{ public virtual DbSet<User> Users { get; set; } public WS_WebAppContext() : base("name=WS_WebAppContext")
{ }
}
}

  Control里面轻松访问,只是给出了登录验证部分:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using Test.Models; namespace Test.Controllers
{
public class HomeController : Controller
{ WS_WebAppContext entity = new WS_WebAppContext(); //登录页面
public ActionResult Login()
{
return View();
} //检查登录信息
[HttpPost]
public ActionResult Login(User u)
{
var logined = entity.Users.SingleOrDefault(m => m.Account == u.Account);
if (!string.IsNullOrWhiteSpace(u.Password) && logined != null && logined.Password == u.Password)
{
String role = "User";
if (logined.IsAdmin)
{
role = "Admin";
}
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
,
logined.Id.ToString(),
DateTime.Now,
DateTime.Now.AddMinutes(),
false,
role
);
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
Response.Cookies.Add(authCookie);
if (logined.IsAdmin)
{
return RedirectToAction("Index", "Admin");//跳转到管理员的主页
}
else
{
return RedirectToAction("Index", "User");//跳转到用户的主页
}
}
else
{
return Content("<script>alert('用户名或密码错误!');local.href='/Home/Index'</script>");
}
}
}
}

  HomeController里面的entity对象就是专门用来访问数据库的,通过它可以简单方便的对数据库里面的数据表(entity.Users就对应着数据库中的用户表)进行增删查改。

当我看到它的简洁方便之处时,灵感来了,我就在想,为什么我不用这种以对象的方式来实现那个专门用于访问xml数据文件的动态链接库呢?

  对于为什么要以对象的方式来访问xml数据表就简单介绍到这里,关键是你要动手去开发过,你才知道这种方式的简洁方便之处。

  让我们在(三)中接着详谈怎样以对象的方式来访问xml数据表。

以对象的方式来访问xml数据表(二)的更多相关文章

  1. 以对象的方式来访问xml数据表(三)

    怎样以对象的方式来访问xml数据表? 在讲如何具体实现(二)中所说的专门用于访问xml文件的动态链接库之前,我们先来看看这个动态链接库具体要实现什么功能. 动态链接库IXmlDB.dll的功能: 1. ...

  2. 以对象的方式来访问xml数据表(一)

    所有实例代码都是以C#演示—— 在将如何以对象的方式来访问xml数据表之前,我们先来谈谈如何用xml文件作为数据库吧! 平时在开发一些小的应用的时候,需要一个数据库,这个时候虽然可以用SQL serv ...

  3. Ajax跨域访问XML数据的另一种方式——使用YQL查询语句

    XML数据默认是不能在客户端通过Ajax跨域请求读取的,一般的做法是在服务器上写一个简单的代理程序,将远程XML的数据先读到本地服务器,然后客户端再从本地服务器通过Ajax来请求.由于我们不能对数据源 ...

  4. wcf序列化大对象时报错:读取 XML 数据时,超出最大

    错误为: 访问服务异常:格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出 错: request.InnerException 消息是“反序 ...

  5. 使用Entity Framework通过code first方式创建数据库和数据表

    开发环境 WIN10 Entity Framework6.0  MVC5.0  开发工具 VS2015  SqlServer2012 1.创建上下文Context继承DbContext,并创建其他的业 ...

  6. SpringMVC06以对象的方式获取前台的数据

    ========创建需要的两个实体类================ public class School { private String sName; private String addres ...

  7. 使用JavaScript访问XML数据

    在本篇文章中,我们将讲述如何在IE中使用ActiveX功能来访问并解析XML文档,由此允许网络冲浪者操纵它们.这一网页将传入并运行脚本的初始化.你一定确保order.xml文档与jsxml.html在 ...

  8. hibernate中.hbm.xml和注解方式自动生成数据表的简单实例(由新手小白编写,仅适用新手小白)

    绝逼新手小白,so 请大神指点! 如果真的错的太多,错的太离谱,错的误导了其他小伙伴,还望大神请勿喷,大神请担待,大神请高抬贵嘴......谢谢. 好了,正题 刚接触ssh,今天在搞使用.hbm.xm ...

  9. Android开发之使用DefaultHandler处理XML数据

    一.定义规则 XML数据结构定义 请记住上面的定义,后面我会用“标签开始”.“文本”.“标签结束”表示SAX正在处理哪部分XML数据 事件模型 为什么这里我要谈到这个,因为SAX处理XML数据是采用事 ...

随机推荐

  1. Strategy策略设计模式

    1.策略模式和状态模式的区别和联系(本部分转载自:http://letscoding.cn/java%E4%B8%AD%EF%BC%8C%E7%8A%B6%E6%80%81%E6%A8%A1%E5%B ...

  2. SQL语句调优-基础知识准备

    当确定了应用性能问题可以归结到某一个,或者几个耗时资源的语句后,对这些语句进行调优,就是数据库管理员或者数据库应用程序开发者当仁不让的职责了.语句调优是和数据库打交道的必备基本功之一. 当你面对一个“ ...

  3. Nhibernate基础

    Nhibernate(英文冬眠的意思) 常用方法 Contains Evict Clear  在 NHibernate 中一切必须是 Virtual 的吗? http://www.cnblogs.co ...

  4. JMir——Java版热血传奇2之资源文件与地图

    我虽然是90后,但是也很喜欢热血传奇2(以下简称“传奇”)这款游戏. 进入程序员行业后自己也对传奇客户端实现有所研究,现在将我的一些研究结果展示出来,如果大家有兴趣的话不妨与我交流. 项目我托管到co ...

  5. Jdbc如何从PostgreSql读取海量数据?PostgreSql源代码分析纪录

    前言: 最近做数据同步,需要从PostgreSql获取数据,发现一旦数据比较多,那么读取的速度非常慢,并且内存占用特别多&GC不掉. 代码样例: 为了方便讲解,下面写了事例代码,从b2c_or ...

  6. android中的提示信息显示方法(toast应用)

    android中的提示信息显示方法(toast应用) (2011-10-17 11:02:06) 转载▼ 标签: android toast 杂谈 分类: Android android中toast的 ...

  7. Adobe flash player更新失败

  8. Android SDK Manager无法显示可供下载的未安装SDK解决方案

    FAQ: 问下的 我的ANDROID SDK MANAGER里原来下载了一些SDK,但是我现在想重新下载新的SDK,咋Packages列表没显示呢?该怎么办? Answer: 据说dl-ssl.goo ...

  9. sitemesh2在tomcat和weblogic中同时使用的配置问题

    (一)拦截*.do,装饰器中匹配do tomcat 可行 weblogic 不可行 web.xml ~~~ <filter> <filter-name>sitemesh< ...

  10. 让C程序更高效的10种方法(转)

    原文:http://blog.jobbole.com/1198/ 代码之美,不仅在于为一个给定问题找到解决方案,而且还在代码的简单性.有效性.紧凑性和效率(内存).代码设计比实际执行更难 .因此,每一 ...