第二篇 《XML 类化生成工具》

插图


注释说明
 
        开发平台 Delphi2007 :
       背景分析: 在程序开发,我们时常要用到XML类型的配置文件。以往,我们读写这些配置文件时只是使用传统的XML类或接口,也有使用第三方控件,以遍历循环查找树为最多。面对纷繁复杂的应用程序,针对不同的配置文件,不同的逻辑,我们要做的分析工作越来越多。基于面象对象编程思想,我们可以把一个XML文档结构类化,使其更清析,快捷,方便地为我们服务。于是,就有了本程序。它可以让你更方便的重构配置文件的代码,更方便的读写XML文档内容,更直观的操作XML文档。
主要代码

XDA.pas
为文档处理单元,负责以统一的文档存储方式存储目标代码的树状结构。包含接口
  IXDADocument = interface;  {XDA文档}
  IXDA_Document = interface;  {Document节点,目标代码树对应的文档性描述}
  IXDA_Root = interface;  {Root节点,目标代码树的根节点}
  IXDA_Nodes = interface;  {集合,包含 IXDA_Node}
  IXDA_Node = interface;  {元素,表示目标代码树中非集合性,非属性节点}
  IXDA_Collections = interface; {集合,包含 IXDA_Item}
  IXDA_Item = interface;  {元素,表示目标代码树中集合性节点}
  IXDA_Elements = interface;  {集合,包含 IXDA_Element}
  IXDA_Element = interface;  {元素,IXDA_Item的唯一子节点}
  IXDA_Attributes = interface;  {集合,所有的属性节点集}
  IXDA_Attribute = interface;  {元素,属性节点}
及实现类
  TXDADocument = Class;
  TXDA_Document = class;
  TXDA_Root = class;
  TXDA_Nodes = class;
  TXDA_Node = class;
  TXDA_Collections = class;
  TXDA_Item = class;
  TXDA_Elements = class;
  TXDA_Element = class;
  TXDA_Attributes = class;
  TXDA_Attribute = class;

接口及实现类的图形表示如下,


 
类声明如下,

Type

  IXDADocument = interface;
  IXDA_Document = interface;
  IXDA_Root = interface;
  IXDA_Nodes = interface;
  IXDA_Node = interface;
  IXDA_Collections = interface;
  IXDA_Item = interface;
  IXDA_Elements = interface;
  IXDA_Element = interface;
  IXDA_Attributes = interface;
  IXDA_Attribute = interface;

{ IXDADocument = interface  }
  IXDADocument = interface(IInterface)
    ['{FA91287A-7873-4335-A5D4-9F7FD05C493E}']
    function GetXDA_Document: IXDA_Document;
    procedure LoadFromFile(Const FileName:string);
    procedure SaveToFile(Const FileName:string);
    procedure SetXDA_Document(const Value: IXDA_Document);
    property XDA_Document: IXDA_Document read GetXDA_Document write
        SetXDA_Document;
  end;

{ IXDA_Document   }
  IXDA_Document = interface(IXMLNode)
    ['{02FE248A-E2CC-445A-ACB2-24290BC870BC}']
    function GetAttrID: WideString;
    function GetEncode: string;
    function GetName: WideString;
    function GetXDA_Attributes: IXDA_Attributes;
    function GetXDA_Collections: IXDA_Collections;
    function GetXDA_Elements: IXDA_Elements;
    function GetXDA_Nodes: IXDA_Nodes;
    function GetXDA_Root: IXDA_Root;
    procedure SetAttrID(const Value: WideString);
    procedure SetEncode(const Value: string);
    procedure SetName(const Value: WideString);
    procedure SetXDA_Attributes(const Value: IXDA_Attributes);
    procedure SetXDA_Collections(const Value: IXDA_Collections);
    procedure SetXDA_Elements(const Value: IXDA_Elements);
    procedure SetXDA_Nodes(const Value: IXDA_Nodes);
    procedure SetXDA_Root(const Value: IXDA_Root);
    property AttrID: WideString read GetAttrID write SetAttrID;
    property Encode: string read GetEncode write SetEncode;
    property Name: WideString read GetName write SetName;
    property XDA_Attributes: IXDA_Attributes read GetXDA_Attributes write
        SetXDA_Attributes;
    property XDA_Collections: IXDA_Collections read GetXDA_Collections write
        SetXDA_Collections;
    property XDA_Elements: IXDA_Elements read GetXDA_Elements write
        SetXDA_Elements;
    property XDA_Nodes: IXDA_Nodes read GetXDA_Nodes write SetXDA_Nodes;
    property XDA_Root: IXDA_Root read GetXDA_Root write SetXDA_Root;
  end;

{ IXDA_Root   }
  IXDA_Root = interface(IXMLNode)
    ['{7854E139-0EFD-4D18-A920-E2263238BC2D}']
    function GetAttrID: WideString;
    function GetName: WideString;
    procedure SetAttrID(const Value: WideString);
    procedure SetName(const Value: WideString);
    property AttrID: WideString read GetAttrID write SetAttrID;
    property Name: WideString read GetName write SetName;
  end;

{ IXDA_Nodes   }
  IXDA_Nodes = interface(IXMLNodeCollection)
    ['{2DABCF69-37DD-441E-9DDA-BD8C68080BA9}']
    function Add: IXDA_Node;
    function Find(const AttributeName:string;const Value:string): IXDA_Node;
    function GetXDA_Node(const Index:integer): IXDA_Node;
    function Insert(const Index: Integer): IXDA_Node;
    property XDA_Nodes[const Index:integer]: IXDA_Node read GetXDA_Node;
  end;

{ IXDA_Node   }
  IXDA_Node = interface(IXMLNode)
    ['{C2ECF6DE-DFBA-403F-B341-5B3C8F41169D}']
    function GetAttrID: WideString;
    function GetName: WideString;
    function GetParent: WideString;
    procedure SetAttrID(const Value: WideString);
    procedure SetName(const Value: WideString);
    procedure SetParent(const Value: WideString);
    property AttrID: WideString read GetAttrID write SetAttrID;
    property Name: WideString read GetName write SetName;
    property Parent: WideString read GetParent write SetParent;
  end;

{ IXDA_Collections   }
  IXDA_Collections = interface(IXMLNodeCollection)
    ['{6664FA02-0B51-4D21-90CF-15EBDB5E7F41}']
    function Add: IXDA_Item;
    function Find(const AttributeName:string;const Value:string): IXDA_Item;
    function GetXDA_Item(const Index:integer): IXDA_Item;
    function Insert(const Index: Integer): IXDA_Item;
    property XDA_Items[const Index:integer]: IXDA_Item read GetXDA_Item;
  end;

{ IXDA_Item   }
  IXDA_Item = interface(IXMLNode)
    ['{5723BB0E-E278-4C81-B988-C124D6C9EC16}']
    function GetAttrID: WideString;
    function GetName: WideString;
    function GetParent: WideString;
    procedure SetAttrID(const Value: WideString);
    procedure SetName(const Value: WideString);
    procedure SetParent(const Value: WideString);
    property AttrID: WideString read GetAttrID write SetAttrID;
    property Name: WideString read GetName write SetName;
    property Parent: WideString read GetParent write SetParent;
  end;

{ IXDA_Elements   }
  IXDA_Elements = interface(IXMLNodeCollection)
    ['{4679C996-DC04-48E5-963D-96EC056FED92}']
    function Add: IXDA_Element;
    function Find(const AttributeName:string;const Value:string): IXDA_Element;
    function GetXDA_Element(const Index:integer): IXDA_Element;
    function Insert(const Index: Integer): IXDA_Element;
    property XDA_Elements[const Index:integer]: IXDA_Element read
        GetXDA_Element;
  end;

{ IXDA_Element   }
  IXDA_Element = interface(IXMLNode)
    ['{0C08B611-89C4-4ECB-B6B4-FCA114ED87D1}']
    function GetAttrID: WideString;
    function GetName: WideString;
    function GetParent: WideString;
    procedure SetAttrID(const Value: WideString);
    procedure SetName(const Value: WideString);
    procedure SetParent(const Value: WideString);
    property AttrID: WideString read GetAttrID write SetAttrID;
    property Name: WideString read GetName write SetName;
    property Parent: WideString read GetParent write SetParent;
  end;

{ IXDA_Attributes   }
  IXDA_Attributes = interface(IXMLNodeCollection)
    ['{A584E860-7653-4C0F-A287-A82EC118D797}']
    function Add: IXDA_Attribute;
    function Find(const AttributeName:string;const Value:string):
        IXDA_Attribute;
    function GetXDA_Attribute(const Index:integer): IXDA_Attribute;
    function Insert(const Index: Integer): IXDA_Attribute;
    property XDA_Attributes[const Index:integer]: IXDA_Attribute read
        GetXDA_Attribute;
  end;

{ IXDA_Attribute   }
  IXDA_Attribute = interface(IXMLNode)
    ['{D1B386BF-C290-4FF4-BF55-51D3E3B681B5}']
    function GetName: WideString;
    function GetValue: WideString;
    procedure SetName(const Value: WideString);
    procedure SetValue(const Value: WideString);
    property Name: WideString read GetName write SetName;
    property Value: WideString read GetValue write SetValue;
  end;


  TXDADocument = Class;
  TXDA_Document = class;
  TXDA_Root = class;
  TXDA_Nodes = class;
  TXDA_Node = class;
  TXDA_Collections = class;
  TXDA_Item = class;
  TXDA_Elements = class;
  TXDA_Element = class;
  TXDA_Attributes = class;
  TXDA_Attribute = class;

{ TXDADocument }
  TXDADocument = class(TInterfacedObject, IXDADocument)
  private
    FXml: IXmlDocument;
  protected
    function GetXDA_Document: IXDA_Document;
    procedure SetXDA_Document(const Value:IXDA_Document);
  public
    constructor Create;
    destructor Destroy; override;
    procedure LoadFromFile(Const FileName:string);
    procedure SaveToFile(Const FileName:string);
  end;

{ TXDA_Document }
  TXDA_Document = class(TXMLNode, IXDA_Document)
  protected
    function GetAttrID: WideString;
    function GetEncode: string;
    function GetName: WideString;
    function GetXDA_Attributes: IXDA_Attributes;
    function GetXDA_Collections: IXDA_Collections;
    function GetXDA_Elements: IXDA_Elements;
    function GetXDA_Nodes: IXDA_Nodes;
    function GetXDA_Root: IXDA_Root;
    procedure SetAttrID(Const Value:WideString);
    procedure SetEncode(const Value:string);
    procedure SetName(Const Value:WideString);
    procedure SetXDA_Attributes(Const Value:IXDA_Attributes);
    procedure SetXDA_Collections(Const Value:IXDA_Collections);
    procedure SetXDA_Elements(Const Value:IXDA_Elements);
    procedure SetXDA_Nodes(Const Value:IXDA_Nodes);
    procedure SetXDA_Root(Const Value:IXDA_Root);
  public
    procedure AfterConstruction; override;
  end;

{ TXDA_Root }
  TXDA_Root = class(TXMLNode, IXDA_Root)
  protected
    function GetAttrID: WideString;
    function GetName: WideString;
    procedure SetAttrID(Const Value:WideString);
    procedure SetName(Const Value:WideString);
  end;

{ TXDA_Nodes }
  TXDA_Nodes = class(TXMLNodeCollection, IXDA_Nodes)
  protected
    function Add: IXDA_Node;
    function Find(const AttributeName:string;const Value:string): IXDA_Node;
    function GetXDA_Node(const Index: Integer): IXDA_Node;
    function Insert(const Index: Integer): IXDA_Node;
  public
    procedure AfterConstruction; override;
  end;

{ TXDA_Node }
  TXDA_Node = class(TXMLNode, IXDA_Node)
  protected
    function GetAttrID: WideString;
    function GetName: WideString;
    function GetParent: WideString;
    procedure SetAttrID(Const Value:WideString);
    procedure SetName(Const Value:WideString);
    procedure SetParent(Const Value:WideString);
  end;

{ TXDA_Collections }
  TXDA_Collections = class(TXMLNodeCollection, IXDA_Collections)
  protected
    function Add: IXDA_Item;
    function Find(const AttributeName:string;const Value:string): IXDA_Item;
    function GetXDA_Item(const Index: Integer): IXDA_Item;
    function Insert(const Index: Integer): IXDA_Item;
  public
    procedure AfterConstruction; override;
  end;

{ TXDA_Item }
  TXDA_Item = class(TXMLNode, IXDA_Item)
  protected
    function GetAttrID: WideString;
    function GetName: WideString;
    function GetParent: WideString;
    procedure SetAttrID(Const Value:WideString);
    procedure SetName(Const Value:WideString);
    procedure SetParent(Const Value:WideString);
  end;

{ TXDA_Elements }
  TXDA_Elements = class(TXMLNodeCollection, IXDA_Elements)
  protected
    function Add: IXDA_Element;
    function Find(const AttributeName:string;const Value:string): IXDA_Element;
    function GetXDA_Element(const Index: Integer): IXDA_Element;
    function Insert(const Index: Integer): IXDA_Element;
  public
    procedure AfterConstruction; override;
  end;

{ TXDA_Element }
  TXDA_Element = class(TXMLNode, IXDA_Element)
  protected
    function GetAttrID: WideString;
    function GetName: WideString;
    function GetParent: WideString;
    procedure SetAttrID(Const Value:WideString);
    procedure SetName(Const Value:WideString);
    procedure SetParent(Const Value:WideString);
  end;

{ TXDA_Attributes }
  TXDA_Attributes = class(TXMLNodeCollection, IXDA_Attributes)
  protected
    function Add: IXDA_Attribute;
    function Find(const AttributeName:string;const Value:string):
        IXDA_Attribute;
    function GetXDA_Attribute(const Index: Integer): IXDA_Attribute;
    function Insert(const Index: Integer): IXDA_Attribute;
  public
    procedure AfterConstruction; override;
  end;

{ TXDA_Attribute }
  TXDA_Attribute = class(TXMLNode, IXDA_Attribute)
  protected
    function GetName: WideString;
    function GetValue: WideString;
    procedure SetName(Const Value:WideString);
    procedure SetValue(Const Value:WideString);
  end;


示例参考 test.xda
<?xml version="1.0"?>
<Document Name="Test" Encod="GB2312" AttrID="">
  <Root Name="Application" AttrID=""/>
  <Nodes/>
  <Collections>
    <Item Name="Child" Parent="Application" AttrID=""/>
  </Collections>
  <Elements>
    <Element Name="Item" Parent="Child" AttrID="Item"/>
  </Elements>
  <Attributes>
    <Attribute Name="Item" Value="Name:WideString;Value:integer;"/>
  </Attributes>
</Document>

注:IXDADocument的根节点,即 IXDA_Document ,是在 TXDADocument 创建时就创建的。其它,如 IXDA_Root ,可在编码时手动创建,方法 xdaRoot:=XdaDoc.AddChild('Root'); //XdaDoc:IXDA_Document;


ClassTypeDef.pas
节点类型定义,包含 属性节点 TNodeAttribute 及类型节点 TNodeType 两种类型
图形表示如下,



类声明如下,
  TNodeAttribute = class
  private
    FName: string;
    FAttribute: string;
   
  protected
    procedure SetAttribute(const Value: string);
    procedure SetName(const Value: string);

  public
    property Name:string read FName write SetName;
    property Attribute:string read FAttribute write SetAttribute;
    function Assign(const Source:TNodeAttribute):Boolean ;
  end;

  TNodeType = class
  private
    FName: string;
    FAttributes:TList; //属性列表
    FChildren: TList;  //子节点列表
    FParent: TNodeType;
    FIsCollection: Boolean;
    FID: TGUID;//标识自己
    FIsRoot: Boolean;
    FHasChildren: Boolean;
    FDescription: string;

    function CheckChildExist(const Child:TNodeType):Integer;    //子节点是否已存在 [Name]
    function CheckAttExist(const Value: TNodeAttribute):Integer;//属性是否已存在   [Name]

  protected
    function  GetAttributes(const index:Integer):TNodeAttribute;
    function  GetChildren(const index:Integer):TNodeType;
    procedure SetIsCollection(const Value: Boolean);
    procedure SetIsRoot(const Value: Boolean);
    procedure SetName(const Value: string);
    procedure SetParent(const Value: TNodeType);
    procedure SetDescription(const Value: string);
    function  GetAttributesCount:Integer;
    function  GetChildrenCount:Integer;
    function  GetHasChildren:Boolean;

  public
    constructor Create();
    destructor  Destroy();override;
    property ID:TGUID read FID;
    property Name:string read FName write SetName;
    property Parent:TNodeType read FParent write SetParent;
    property IsRoot:Boolean read FIsRoot write SetIsRoot default False;
    property IsCollection:Boolean read FIsCollection write SetIsCollection default False;
    property Attributes[const index:Integer]:TNodeAttribute read GetAttributes;
    property Children[const index:Integer]:TNodeType read GetChildren;
    property HasChildren:Boolean read GetHasChildren;
    property ChildrenCount:Integer read GetChildrenCount;
    property AttributesCount:Integer read GetAttributesCount;
    property Description:string read FDescription write SetDescription;

    function AddAttribute(const Value:TNodeAttribute):Boolean;
    function DeleteAttributes:Boolean;
    function AddChild(const NodeType:TNodeType):Boolean;
    function DeleteAttribute(Att:TNodeAttribute):Boolean;
    function DeleteChild(Child:TNodeType):Boolean;
    function Assign(const Source:TNodeType):Boolean;//拷贝源TNodeType的一些内容
  end;


BuildCodes.pas
为代码生成单元,作用很简单,根据文档结构生成相应的代码。

要点

    一个XML文档,通常情况下的构成为 节点、属性、Text文本值、集合等,我这里只取其中的 节点(TNodeType )、属性(TNodeAttribute )、集合(TNodeType 加一个集合标记 IsCollection ,并且只能有一个子节点),来将一个XML文档树进行结构化。具体实现为
定义文档类 TXmlDocument,其 Root 是 TNodeType类型,依次类推。

程序下载
/Files/goldli/xda.rar


原文地址:https://www.cnblogs.com/goldli/p/1498364.html