主要使用了GetFilterString这个函数,其中TFilterElement、TFilterList都是从TFilter继承过来的。
function TFilterList.GetFilterString: string;
var
  i:integer;
  Node,Node1:IXMLNode;
  tmpFilterElement:TFilterElement;
  tmpFilter:TFilter;
  tmpstr,resultstr,Filterstr:string;
begin
  FFieldXMLDoc.Active :=true ;
  FFieldXMLDoc.Version := '1.0' ;
  FFieldXMLDoc.Encoding := 'GB2312' ;
  Root := FFieldXMLDoc.AddChild('ROOT');  resultstr:='';Filterstr:='';
  for i:=0 to list.Count -1 do
  begin
    tmpFilter:= TFilter(List[i]);
    if tmpFilter is TFilterElement then
    begin
      Node := Root.AddChild('ChildNode');
      tmpFilter.GetFilterXML(Node1);
      Node1 := Node.AddChild(XML_RELATION);
      Node1.Attributes[XML_VAL] := FRelation;
    end
    else if tmpFilter is TFilterList then
    begin
      Node := Root.AddChild('ChildNode');
      Node1 := Node.AddChild(XML_ATTRIBUTE);
      Node1.Attributes[XML_VAL]:=GetXMLList(Node,tmpFilter);
      Node1 := Node.AddChild(XML_RELATION);
      Node1.Attributes[XML_VAL]:= FRelation;
    end;
  end;
  List.Clear;
  FFieldXMLDoc.SaveToFile('D:\test111.xml');
  result := FFieldXMLDoc.xml.strings[1];
end;
TFilterElement、TFilterList、TFilter关系:
  TFilter = class(TObject)
    constructor create;
    destructor destroy;virtual;
  private
    function GetFilterString: string; virtual; abstract;
    function GetFilterXML(Node: IXMLNode): string; virtual; abstract;
  public
    //1 增加子元素
    procedure Add(Filter: TFilter); virtual; abstract;
    //1 清除所有元素
    procedure Clear; virtual; abstract;
    //1 最终得到的查询条件语句
    property FilterString: string read GetFilterString;
  end;  TFilterElement = class(TFilter)
    constructor create;
    destructor destroy;override;
  private
    FCondition: string;
    FFieldName: string;
    FFieldValue: string;
    FValueType: string;
  public
    function GetFilterString: string; override;
    function GetFilterXML(Node: IXMLNode): string;override;
    //1 在元素不用实现add
    procedure Add(Filter: TFilter); override;
    //1 也不用实现clear
    procedure Clear; override;
    //1 查询条件(=,like,>,< ect.)
    property Condition: string read FCondition write FCondition;
    //1 字段名
    property FieldName: string read FFieldName write FFieldName;
    //1 条件值
    property FieldValue: string read FFieldValue write FFieldValue;
    //1 值类型(int,string,date,null)
    property ValueType: string read FValueType write FValueType;
  end;  TFilterList = class(TFilter)
    constructor create;
    destructor destroy;override;
  private
    FRelation: string;
    //1 列表
    List: TObjectList;
    FFieldXMLDoc : TXMLDocument;
    function GetFilterString: string; override;
    function GetFilterXML(Node: IXMLNode): string; override;
    function GetXMLList(Node : IXMLNode;tmpmethod:TFilter):string;
  public
    //1 Add具体实现可以加Element,也可加List
    procedure Add(Filter: TFilter); override;
    //1 Clear实现
    procedure Clear; override;
    //1 列表元素关系
    property Relation: string read FRelation write FRelation;
  end;
在调试中发现,如果TFilterList先add(TFilterElement)后add(TFilterList)后,我所需要的节点均能在XML文件中创建,但是如果我先先add(TFilterList)后add(TFilterElement)后,XML文件中只能得到TFilterList中的内容,无法得到TFilterElement中的内容。百思不得其解,大家能不能给诊断下?

解决方案 »

  1.   

    以下两个函数为GetFilterString要调用到的内容
    function TFilterElement.GetFilterXML(Node: IXMLNode): string;
    var
      Node1 : IXMLNode;
    begin
      Node1 := Node.AddChild(XML_VALUETYPE);
      Node1.Attributes[XML_VAL] := ValueType;
      Node1 := Node.AddChild(XML_FIELDS);
      Node1.Attributes[XML_VAL] := FieldName;
      Node1 := Node.AddChild(XML_CONDITION);
      Node1.Attributes[XML_VAL] := Condition;
      Node1 := Node.AddChild(XML_FIELDVALUE);
      Node1.Attributes[XML_VAL] := FieldValue ;
      result := Node.XML ;
    end;function TFilterList.GetXMLList(Node : IXMLNode;tmpmethod:TFilter):string;
    var
      str,str2:string;
      Node1,Root1 : IXMLNode;
    begin
      str := tmpmethod.GetFilterString;
      result := str;
    end;
      

  2.   

    一来楼主是在周末问问题,
    二来,恕我直言,楼主代码该整理干净些了.
    从贴出来的部分代码,看不出问题.ADD节点部分代码呢?另有一个毛病:
      TFilter = class(TObject)
        destructor destroy;virtual;//应该用override吧,这儿编译器没警告吗?