65.9K
CodeProject 正在变化。 阅读更多。
Home

Xmlawy XML 框架

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.94/5 (18投票s)

2008 年 12 月 29 日

CPOL

2分钟阅读

viewsIcon

31287

downloadIcon

284

访问 XML 文件的基于对象的框架。

引言

这个框架提供了一种简单的方式来访问 XML 文件,支持插入、更新、删除以及像查询 SQL 一样通过查询 XML 来选择数据。

Using the Code

我将从编写简单的代码行开始,演示插入、更新、删除和选择的操作,然后在一个 XML 文件中显示结果。

以下是如何创建 XML 文件并访问对象

static void Main(string[] args)
{
    BaseDataAccess access = 
      new BaseDataAccess("D:/xmltest.xml", "Objects");
}

简单的插入

Insert 方法接受一个类型为 BaseDataObject 的对象作为参数,该对象包含节点名称、值、属性以及一个子节点列表,这些子节点也具有相同的类型。

access.Insert(new BaseDataObject("type", "human")).Execute();
access.Insert(new BaseDataObject("type", "animal")).Execute();

xmlawy/2.png

简单的选择

你可以查询 XML 以选择特定的节点

List<BaseDataObject> dataList = access.Select("type").
                                          Where("type").
                                          IsEqualTo("animal").
                                          ExecuteSelect<BaseDataObject>();

for (int i = 0; i < dataList.Count; i++)
{
    Console.WriteLine(dataList[i].Name + " : " + dataList[i].Value);
}

xmlawy/3.png

更新

也很容易更新特定的节点

access.Update("type").Set("type").EqualTo("animal").
       Where("type").IsEqualTo("human").Execute();

xmlawy/4.png

Deleting(删除中)

以下是如何删除

access.Delete("type").Where("type").IsEqualTo("animal").Execute();

xmlawy/6.png

高级插入

插入子节点的子节点的方法是创建一个 BaseDataObject 列表,并将它们插入到另一个 BaseDataObject 的子节点列表中。(最好的方法是递归地进行。)以下代码插入三层深度的子节点

static void Main(string[] args)
{
    // ACCESS
    BaseDataAccess access = 
      new BaseDataAccess("test.xml", "objects");

    // INSERTING 3 LEVELS IN DEPTH
    List<BaseDataObject> parents = new List<BaseDataObject>();
    for (int i = 0; i < 5; i++)
    {
        parents.Add(new BaseDataObject("Parent", MakeChilds(5)));
    }
    BaseDataObject parentOfParents = 
       new BaseDataObject("GrandParent", parents);
    access.Insert(parentOfParents).Execute();

    Console.WriteLine(access.XmlString);

    Console.ReadLine();
}

private static List<BaseDataObject> MakeChilds(int count)
{
    List<BaseDataObject> childs = new List<BaseDataObject>();
    for (int i = 0; i < count; i++)
    {
        childs.Add(new BaseDataObject("N" + i.ToString(), 
                   "V " + i.ToString()));
    }
    return childs;
}

xmlawy/7.png

高级选择

以下是如何递归地选择所选对象中的任何子节点,使用 PrintObject(obj) 方法

static void Main(string[] args)
{
    // ACCESS
    BaseDataAccess access = new BaseDataAccess("test.xml", "objects");

    // INSERTING 3 LEVELS IN DEPTH
    List<BaseDataObject> parents = new List<BaseDataObject>();
    for (int i = 0; i < 5; i++)
    {
        parents.Add(new BaseDataObject("Parent", MakeChilds(5)));
    }
    BaseDataObject parentOfParents = new BaseDataObject("GrandParent", parents);
    access.Insert(parentOfParents).Execute();

    // SELECTING
    List<BaseDataObject> objects = 
      access.Select("GrandParent").ExecuteSelect<BaseDataObject>();
    for (int i = 0; i < objects.Count; i++)
    {
        PrintObject(objects[i]);
    }

    Console.ReadLine();
}

private static List<BaseDataObject> MakeChilds(int count)
{
    List<BaseDataObject> childs = new List<BaseDataObject>();
    for (int i = 0; i < count; i++)
    {
        childs.Add(new BaseDataObject("N" + i.ToString(), 
                   " V" + i.ToString() + " "));
    }
    return childs;
}

private static void PrintObject(BaseDataObject obj)
{
    if (obj.Childs.Count > 0)
    {
        Console.WriteLine(obj.Name + " >");
        for (int i = 0; i < obj.Childs.Count; i++)
        {
            PrintObject(obj.Childs[i]);
        }
    }
    else
    {
        Console.WriteLine(obj.Name + " : " + obj.Value);
    }
}

xmlawy/8.png

插入简单对象

如果你想快速将对象的属性保存到 XML 中(简单的序列化),还有另一个泛型 Insert 方法,它接受任何对象作为参数,并将所有类型为 stringint 的属性插入到 XML 文件中。

class MyClass
{
    public MyClass()
    {
        Age = 20;
        FirstName = "Islam";
        LastName = "Eldemery";
        Address = "Egypt, Cairo, bla bla bla";
    }

    public int Age { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        MyClass obj = new MyClass();

        // ACCESS
        BaseDataAccess access = new BaseDataAccess("test.xml", "objects");

        // INSERT
        access.Insert<MyClass>(obj).Execute();

        Console.WriteLine(access.XmlString);

        Console.ReadLine();
    }
}

xmlawy/9.png

目前为止一切都很好,让我们深入研究一下..

重写基类中的虚方法

假设你想在插入后加密 XML,并在选择之前解密它。这可以通过如下重写基类方法轻松完成

class XmlAccess : BaseDataAccess
{
    XMLEncryptor encryptor;

    public XmlAccess(string path, string rootElement)
        : base(path, rootElement)
    {
        encryptor = new XMLEncryptor(path);
    }

    public override bool Execute()
    {
        bool executed = base.Execute();

        ///////////////////////////////////////////////////
        // ENCRYPTOR GOES HERE
        encryptor.Encrypt(base._objectToInsert.Name, "myKey");
        ///////////////////////////////////////////////////

        return executed;
    }

    public override List<T> ExecuteSelect<T>()
    {
        ///////////////////////////////////////////////////
        // ENCRYPTOR GOES HERE
        encryptor.Decrypt("myKey");
        ///////////////////////////////////////////////////

        return base.ExecuteSelect<T>();
    }
}

选择所有节点

你也可以用一行代码选择根节点中的所有节点,包括所有子节点和子节点的子节点。

List<BaseDataObject> objects = access.SelectAll<BaseDataObject>();

再次说明,这是为了递归地遍历它们

static void Main(string[] args)
{
    // ACCESS
    BaseDataAccess access = 
      new BaseDataAccess(@"D:\XmlFiles\StructureMap.xml", 
                         "doesntMatter");

    // SELECTING
    List<BaseDataObject> objects = access.SelectAll<BaseDataObject>();

    // DISPLAYING
    for (int i = 0; i < objects.Count; i++)
        PrintObject(objects[i]);

    Console.ReadLine();
}

private static void PrintObject(BaseDataObject obj)
{
    if (obj.Childs.Count > 0)
    {
        Console.WriteLine(obj.Name + " >");

        for (int i = 0; i < obj.Childs.Count; i++)
            PrintObject(obj.Childs[i]);
    }
    else
        Console.WriteLine(obj.Name + " : " + obj.Value);
}

历史

库中的代码已完全注释。这是版本 1。我希望我们将来能够添加更多功能。

© . All rights reserved.