以对象的方式来访问xml数据表(二)

  为什么要以对象的方式来访问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 < 5 || path_.Substring(path_.Length - 3).ToLower() != "xml")
                {
                    return false;
                }
                noteName = noteName_;//记录每条记录的名称
                xmlFilePath = path_;//记录文件路径

                if (path_.LastIndexOf("\\") > 0)
                {
                    path_ = path_.Substring(0, 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() > 0)
                    {
                        int newNo;
                        var lastNote = from Note in Notes.Elements() select Convert.ToInt32(Note.Attribute("No").Value);
                        newNo = lastNote.Max() + 1;
                        Notes.LastNode.AddAfterSelf(noteName, new XAttribute("No", newNo));
                        for (int i = 0; i < xmlProperties.Length; i++)
                        {
                            if (i == 0)
                            {
                                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", 1)));
                        for (int i = 0; i < xmlProperties.Length; i++)
                        {
                            if (i == 0)
                            {
                                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() > 0)
                    {
                        int newNo;
                        var lastNote = from Note in Notes.Elements() select Convert.ToInt32(Note.Attribute("No").Value);
                        newNo = lastNote.Max() + 1;
                        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", 1));
                        }
                        else
                        {
                            newNote.Attribute("No").Value = "1";
                        }
                        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() > 0)
                    {
                        int newNo;
                        var lastNote = from Note in Notes.Elements() select Convert.ToInt32(Note.Attribute("No").Value);
                        newNo = lastNote.Max() + 1;
                        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", 1));
                        }
                        else
                        {
                            newNote.Attribute("No").Value = "1";
                        }
                        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 = 0; i < propertyValues.Length; i++)
                        {
                            if (propertyValues[i] == "") continue;
                            if (Notes.Elements(noteName).Count() == 0) 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() == 0) 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() == 0) return false;//数据文件内容为空
                var proNote = Notes.Elements(noteName).Attributes("No").SingleOrDefault(m => m.Value == no);
                if (proNote != null)
                {
                    var proSubNotes = proNote.Parent.Elements();
                    int i = 0;
                    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() == 0) 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 == 0)//返回所有数据
                {
                    return Notes.Elements(noteName);
                }
                if (no == "" && propertyValues.Length != 0)
                {
                    for (int i = 0; i < propertyValues.Length; i++)
                    {
                        if (propertyValues[i] == "") continue;
                        if (Notes.Elements(noteName).Count() == 0) return result;//数据文件内容为空
                        var proNotes = Notes.Elements(noteName).Elements(xmlProperties[i]).Where(m => m.Value == propertyValues[i]);
                        return proNotes;
                    }
                }
                else
                {
                    if (Notes.Elements(noteName).Count() == 0) 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() > 0)
                    return (from Note in Notes.Elements(noteName) select Convert.ToInt32(Note.Attribute("No").Value)).Max();
                else
                    return 0;
            }
            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(
                    1,
                    logined.Id.ToString(),
                    DateTime.Now,
                    DateTime.Now.AddMinutes(120),
                    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数据表。

时间: 2024-10-01 03:24:01

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

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

怎样以对象的方式来访问xml数据表? 在讲如何具体实现(二)中所说的专门用于访问xml文件的动态链接库之前,我们先来看看这个动态链接库具体要实现什么功能. 动态链接库IXmlDB.dll的功能: 1.对于不同的对象具有通用性.(简单地说就是在不修改内部代码的情况下,可以用不同的对象去映射不同的xml数据表) 由于数据保存在xml数据表里,所有数据都是以字符串的形式保存的,那么与之对应的对象里的属性就可以全部统一为string类型. 类与xml数据表映射的两个实例代码: User类与其对应xml数

使用JavaScript访问XML数据

在本篇文章中,我们将讲述如何在IE中使用ActiveX功能来访问并解析XML文档,由此允许网络冲浪者操纵它们.这一网页将传入并运行脚本的初始化.你一定确保order.xml文档与jsxml.html在相同的相同的路径上.初始化部分将一个新的ActiveX对象例示为MSXML2.DOMDocument.3.0对象类型,然后脚本传入order.xml文档到内存中,并选择所有的/Order/Item节点.我们使用/Order/Item节点以识别文档已经包含的选项.文档中的标准有一个onLoad属性,这

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

XML数据默认是不能在客户端通过Ajax跨域请求读取的,一般的做法是在服务器上写一个简单的代理程序,将远程XML的数据先读到本地服务器,然后客户端再从本地服务器通过Ajax来请求.由于我们不能对数据源所在的环境进行任何设置和修改,所以仅通过客户端代码很难绕过这个问题.但如果请求的数据不是XML而是JSON对象或者JavaScript函数,则通过JSONP方法可以非常容易地解决,直接调用JQuery.getJSON()方法在回调函数中就可以获取到返回的结果.如果要使用JSONP,可以在指定的URL

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

开发环境 WIN10 Entity Framework6.0  MVC5.0  开发工具 VS2015  SqlServer2012 1.创建上下文Context继承DbContext,并创建其他的业务类,这些业务类会创建对应的数据表. 1 public class AccountContext:DbContext 2 { 3 public AccountContext():base("AccountContext") { } 4 public DbSet<SysUser>

MySQL学习12:修改数据表(二)

我们接着上一篇的添加约束的操作讲述. 三添加约束 (3)添加外键约束 ALTER TABLE table_name ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] [index_type] (index_col_name,...) references_definition; 例子: ALTER TABLE users2 ADD FOREIGN KEY (pid) REFERENCES provinces (id); SHOW COLUMNS

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

========创建需要的两个实体类================ /** * @author 小豆腐 */ public class Student { private String name; private int age; //学生的老师 private Teacher teacher; public Teacher getTeacher() { return teacher; } public void setTeacher(Teacher teacher) { this.teach

java解析xml数据(使用jaxp的方式)

解析xml主要有两种方式,一种是dom方式,一种是sax的方式. 1.dom方式是将xml数据作为一个对象生成一个树状结构放入内存中, (1)优点:方便对xml中的数据进行增删改,是W3C推荐的处理xml数据的方式 (2)缺点:这种方式不利于读取比较大的xml文件,容易造成内存溢出. 2.sax方式是采用事件驱动,边读边解析,从上往下,一行一行的解析的方式进行操作 (1)优点:在处理比较大的xml文件时不会造成内存溢出的情况 (2)缺点:不能实现增删改的操作,不是官网标准,但是几乎所有的xml解

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

绝逼新手小白,so 请大神指点! 如果真的错的太多,错的太离谱,错的误导了其他小伙伴,还望大神请勿喷,大神请担待,大神请高抬贵嘴......谢谢. 好了,正题 刚接触ssh,今天在搞使用.hbm.xml文件 和 注解方式 来自动生成数据表 其中只是整了spring.hibernate,struts部分没有整.也就是说我只是测试了能够自动生成数据表(自动生成为"标准",自认为是对的......) 下面是配置和代码: 使用工具:myeclipse 2014 ,其中web project项目

XML数据岛,数据绑定参考

1.XML的局限性 目前,许多Web网站的内容数据都存放在数据库或数据文件中.对于Web程序开发人员来说,如果要想把有用的信息从数据库中提取出来,传统的方法是在服务器端编写脚本程序(如VBScript.JavaScript.CGI.ASP.JSP,Perl等等),通过对数据库执行SQL查询得到相关记录,然后把查询结果组织成HTML页面返回给客户端,用户使用浏览器观察最终结果. 为了提高系统服务的灵活性.可扩展性,使服务对象范围更广,许多商业网站都尽可能地把商务规则.原始数据和表现形式当做相互独立