DFM文件与XML文件互转

原创 2004年08月25日 22:17:00

dfm文件是Delphi中存储窗体控件信息的,有时为了对大批量的dfm文件操作(如:批量替换控件、作检查等),往往不是太方便。
XML对结构化的数据读写则很强,将文本类型的dfm转为xml后进行操作,再转回dfm存储大大方便了操作。

 

//DFM to XML
procedure Dfm2Xml(ADfmStrings: TStrings; AXml: IDsXmlDocument);
Var
  i: integer;
  mStr : string;
  mParentNode, mNode : IDsXMLNode;
  mObjName, mClass, mObjType: string;
  mPropName, mPropValue: string;
  mInItem: Boolean;   //有Item的也会有End相对,所以要和Object end分开
begin
  mInItem := False;
  mParentNode := AXML;
  for i:=0 to ADfmStrings.Count - 1 do
  begin
    mStr := trim(ADfmStrings.Strings[i]);
    //对象开始
    if (copy(mStr, 1, 6) = 'object') or (copy(mStr, 1, 9) = 'inherited') then
    begin
      //先写入属性 - 如果还有属性没有写
      if mPropName <> '' then
      begin
        mNode := AXml.createElement(mPropName);
        mNode.text := mPropValue;
        mParentNode.appendChild(mNode);
        mPropName := '';
      end;
      mObjType := CutToken(mStr, ' ');          //Type: object or inherited
      mObjName := CutToken(mStr, ': ');         //ObjName: Ex. frmCmsI03
      mClass := mStr;                           //ClassName: Ex. TButton
      mNode := AXml.createElement(mObjName);
      (mNode as IDsXmlElement).setAttribute('ObjType', mObjType);
      (mNode as IDsXmlElement).setAttribute('Class', mClass);
      mParentNode.appendChild(mNode);
      mParentNode := mNode;
    end
    //对象结束
    else if (mStr = 'end') and (not mInItem) then
    begin
      //先写入属性
      if mPropName <> '' then
      begin
        mNode := AXml.createElement(mPropName);
        mNode.text := mPropValue;
        mParentNode.appendChild(mNode);
        mPropName := '';
      end;
      mParentNode := mParentNode.parentNode;
    end
    //属性处理
    else
    begin
      //有 = 说明是一个属性的新的开始
      if (Pos(' = ', mStr) > 0) and (not mInItem) then
      begin
        //先写入属性
        if mPropName <> '' then
        begin
          mNode := AXml.createElement(mPropName);
          mNode.text := mPropValue;
          mParentNode.appendChild(mNode);
        end;
        mPropName := CutToken(mStr, ' = ');
        mPropValue := CutToken(mStr, ' = ');
      end
      else   //说明这个属性可能有多行
        mPropValue := mPropValue + '#13#10' + mStr;
        if mStr = 'item' then mInItem := True;
        if mStr = 'end' then mInItem := False;
    end;
  end;
end;
//XML to DFM
procedure Xml2Dfm(AXml: IDsXmlDocument; ADfmStrings: TStrings);
  procedure Node2Dfm(ANode: IDsXMLNode; oString: TStrings; IdentSpace: string);
  Var
    mObjName, mClass, mObjType: string;
    mPropName, mPropValue: string;
    mNode : IDsXMLNode;
    i: integer;
    mVar : Variant;
  begin
    mObjName := (ANode as IDsXmlElement).NodeName;
    mClass   := (ANode as IDsXmlElement).getAttribute('Class');
    mObjType := (ANode as IDsXmlElement).getAttribute('ObjType');
    //写入Object begin
    oString.Add(Format('%s%s %s: %s', [IdentSpace, mObjType, mObjName, mClass]));
    //写入属性
    for i:= 0 to ANode.childNodes.length - 1 do
    begin
      mNode := ANode.childNodes.item[i];
      //Has Child 说明是一个新的对象
      mVar := (mNode as IDsXmlElement).getAttribute('ObjType');
      if not varIsNull(mVar)  then
        Node2Dfm(mNode, oString, IdentSpace + '  ')
      //是属性,写进去就好了.
      else
      begin
        mPropName := mNode.nodeName;
        mPropValue := mNode.text;
        mPropValue := StringReplace(mPropValue, '#13#10', #13#10, [rfReplaceAll]);
        //写入:缩进
        oString.Add(Format('%s%s = %s', [IdentSpace+'  ', mPropName, mPropValue]));
      end;
    end;
    //写入End
    oString.Add(Format('%send', [IdentSpace]));
  end;
  
begin
  Node2Dfm(AXml.Get_documentElement, ADfmStrings, '');
end;

用到的类型:

uses
   MSXML2_TLB;
//类型自己重新定义过
type
  IDsXmlDocument = IXMLDOMDocument2;
  IDsXmlNode     = IXMLDOMNode;
  IDsXmlElement  = IXMLDOMElement;
  IDsXmlNodeList = IXMLDOMNodeList;

Delphi 的DFM文件乱码无法编译的终极解决办法

前几天接手一个老项目,Delphi5开发,发现里面dfm文件报错,无法编译,很奇怪,用NtPD打开一看,里面都是乱码,看来是碰到所谓的delphi dfm文件乱码问题了。于是看是想办法恢复,但是总不能...
  • kokzhu
  • kokzhu
  • 2010-04-07 16:09:00
  • 1074

Delphi实现类的持久化保存(DFM格式)

var inStream,outStream:TMemoryStream; begin inStream:=TMemoryStream.Create; outStream:=TMemory...
  • rocklee
  • rocklee
  • 2015-12-13 00:19:29
  • 896

动态加载DFM界面的小程序(包含源码,适合常规及第三方控件)

  • 2009年04月06日 16:55
  • 569KB
  • 下载

Delphi窗体文件(*.dfm)批量转换为Text格式

Delphi 的窗体文件(*.dfm) 记录了窗体的信息,此文件的保存方式一般有两种:二进制和文本格式。窗体文件保存为文本格式更有意义,因为很多文本比较工具或Source Control Tool内嵌...
  • whw6_faye
  • whw6_faye
  • 2007-02-06 17:35:00
  • 2567

Delphi 对象流式管理---窗体文件(*.dfm)的转换

  • zgqtxwd
  • zgqtxwd
  • 2008-05-01 00:21:00
  • 201

写DFM文件的过程:WriteComponentResFie

   该过程带有两个参数FileName和Instance。FileName参数指定要写入的DFM文件名,Instance参数是TComponent类型的,它指定要写入的部件名,一般是TForm对象的...
  • wjames2000
  • wjames2000
  • 2008-10-14 17:56:00
  • 454

Delphi动态DFM文件应用

    在baidu找资料的时候发现这篇好文章,拷贝过来,有时间了学习学习。来源:http://bbs.szu.edu.cn/bbsanc.php?path=%2Fgroups%2FGROUP_2%2...
  • liuypengway
  • liuypengway
  • 2011-06-23 16:05:00
  • 486

测试Delphi控件属性保存到dfm

控件单元代码: unit TstControl; interface uses Classes, SysUtils, Controls; type   //定义控件的属性类型    类型中的...
  • henreash
  • henreash
  • 2012-02-21 16:56:27
  • 2239

Delphi基础学习笔记—指令{$R*.DFM}作用

1.{$R *.dfm} 2.dcc70.dll调用失败的处理 3.button的快捷键设置&
  • yanni23
  • yanni23
  • 2010-09-01 14:51:00
  • 1878
收藏助手
不良信息举报
您举报文章:DFM文件与XML文件互转
举报原因:
原因补充:

(最多只允许输入30个字)