为什么要以对象的方式来访问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. Mysql 字符串截取

    1.从左开始截取字符串 left(str, length) 说明:left(被截取字段,截取长度) 例:select left(content,200) as abstract from my_con ...

  2. 文件编辑器 vi

    1.关于文本编辑器: 文本编辑器有很多,比如图形模式的gedit.kwrite.OpenOffice ... ... ,文本模式下的编辑器有vi.vim(vi的增强版本)和nano ... ... v ...

  3. memcached 源码阅读笔记

    阅读 memcached 最好有 libevent 基础, memcached 是基于 libevent 构建起来的. 通由 libevent 提供的事件驱动机制触发 memcached 中的 IO ...

  4. 降低屏幕亮度,减缓眼疲劳 (linux/windows/firefox/android)

    Linux 在Linux上自动调整屏幕亮度来保护眼睛 - 51CTO.COM -- 介绍了Camera和RedShift这两款工具 How to automatically dim your scre ...

  5. Entity Framework 在Vs2012下Update Model From DataBase 失败的问题

    http://stackoverflow.com/questions/13054212/vs-2012-ef-5-0-update-model-from-database-not-picking-up ...

  6. centos 7.0 下触发器乱码的解决

    [root@iZ62jhlmmZ ~]# uname -a Linux iZ62jhlmsymZ 3.10.0-123.13.2.el7.x86_64 #1 SMP Thu Dec 18 14:09: ...

  7. PHP读写文件高并发处理实例-转

    背景: 最近公司游戏开发需要知道游戏加载的流失率.因为,我们做的是网页游戏.玩过网页游戏的人都知道,进入游戏前要加载一些资源.最后才能到达创建角色的游戏界面.我们有一个需求就是要统计在加载过程中还未到 ...

  8. Git回滚远程版本

    摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “房子是租的 但生活不是” 1.故事的开始 远程master分支下代码被不小心提交了很多垃圾代码 ...

  9. WinStore控件之TextBox

    1 TextBox简单实例 内容摘要:包含文本的选中,弹出什么类型的键盘,回车隐藏键盘, <Grid Name="root" Background="Transpa ...

  10. C primer plus 练习题 第七章

    1. #include <stdio.h> #define SPACE ' ' #define NEWLINE '\n' int main() { int spaces,newlines, ...