XML(eXtensible Markup Language可扩展标志语言)在近几年的信息类杂志网站上可谓是最抢眼的一词大大小小的信息产品都争相和它搭上关系唯恐赶不及这辆快车有着良好口碑的宝蓝(Borland)系列开发平台也不例外从版开始就集成了XML组件包因其使用MSXMLDom解析器相比于此前广泛应用的XMLParser解析器MSXMLDom更显规范中文兼容性更好(元素名属性名均支持中文)很受开发者青睐为帮助初学者快速掌握Delphi中的XML编程笔者特写此文以供交流
笔者通过一个读写XML文件的实例来说明XML编程的各个步骤只需读者有结点元素属性的基本概念就能容易的理解本文笔者所要读入的XML文件结构如下所示命名为Inputxml
<学生花名册>
<学生 性别 = 男>
<姓名>李华
<年龄>
<电话>
<学生 性别 = 男>
<姓名>张三
<年龄>
<电话>
Inputxml文件的第一行是XML的版本说明属性encoding宣告使用何种字符集建立默认以Unicode 编码(UTF 或UTF)这里用中文GB码第二行<学生花名册>是根元素下面定义了两个学生元素学生下面嵌套了三个子元素是对学生的进一步说明与之相对应的我们在Delphi中定义如下的学生数据结构//后面的文字是对变量或语句的说明下同
TStudent = class {学生}
sex : string; //学生性别
name : string; //学生姓名
age : integer; //学生年龄
phone: string; //电话号码
end;
为了读写我们需要放置两个TXMLDocument控件在Delphi VCL面板的Internet标签页里那个标有XML字样的控件就是当然此控件也可以动态创建但需要包含必要的文件这里为简单起见我们直接放置在窗体上分别命名为InXMLDoc和OutXMLDocInXMLDoc用于调入Inputxml文件OutXMLDoc用于暂存输出到Outputxml的文档
在窗体上放个按钮我们把测试代码直接放置在按钮的单击事件里先定义几个变量用来保存临时信息如下所示
Root : IXMLNode; //指向XML根结点
Parent_Node: IXMLNode; //指向学生结点
Child_node : IXMLNode; //指向学生的子结点
Student : TStudent; //存单个学生信息
List : TList; //存学生列表
i : integer; //循环变量
我们先来读入XML文件代码如下
List := TListCreate; //初始化列表
InXMLDocLoadFromFile(Inputxml); //调入Inputxml文件
Root := InXMLDocDocumentElement; //取XML文件的根结点即<学生花名册>
Parent_Node := RootChildNodesFirst; //使Parent_Node指向学生结点
while (Parent_Node <> nil) do //循环取多个学生可再多加几个学生信息测试
begin
if (Parent_NodeNodeName = 学生) then //判断是否为学生结点
begin
Student := TStudentCreate; //新建一个学生的结构信息
Studentsex := Parent_NodeAttributes[性别]; //取学生的性别属性
Child_Node := Parent_NodeChildNodesFirst;
//使Child_Node指向该学生的第一个子结点信息
while (Child_Node <> nil) do //循环取学生的各个子各点
begin
if (Child_NodeNodeName = 姓名) then //判断是否为姓名结点
Studentname := Child_NodeText //取姓名结点的值取于name字段中
else if (Child_NodeNodeName = 年龄) then //此行起后四行与前两行类似
Studentage := StrToInt(Child_NodeText)
else if (Child_NodeNodeName = 电话) then
Studentphone := Child_NodeText;
Child_Node := Child_NodeNextSibling; //顺序取下一个学生的子结点信息
end;
ListAdd(Student); //把一个学生信息加入列表
end;
Parent_Node := Parent_NodeNextSibling; //顺序取下一个学生信息
end;
到这儿所有的学生信息都已存到List列表里面了读者可以跟蹤代码测试
下面我们把List里的临时学生信息存到Outputxml文件里代码如下
OutXMLDocActive := true; //激活OutXMLDoc自动初始化空的XML文档
OutXMLDocEncoding := GB; //设置字符集
Root := OutXMLDocAddChild(学生花名册); //建根结点
for i := to ListCount do //循环取各个学生信息
begin
Student := ListItems[i]; //顺序取一个学生信息
if (Student <> nil) then
begin
Parent_Node := RootAddChild(学生); //根结点后添加一个学生结点
Parent_NodeAttributes[性别] := Studentsex; //给学生结点设置性别属性
Child_Node := Parent_NodeAddChild(姓名); //学生结点后添加一个姓名结点
Child_NodeText := Studentname; //设置姓名的文本值
Child_Node := Parent_NodeAddChild(年龄); //此行起后四行与前两行类似
Child_NodeText := IntToStr(Studentage);
Child_Node := Parent_NodeAddChild(电话);
Child_NodeText := Studentphone;
end;
end;
OutXMLDocSaveToFile(Outputxml); //把组织好的XML文档存于Outputxml文件中
OutXMLDocActive := false; //钝化(关闭)OutXMLDoc
ListFree; //最后释放保存临时学生信息的列表
好了看看Inputxml和Outputxml内容是不是一样是不是很简单呢?其实在C++ Builder也有相同的组件只需将Pascal语法转换成C++语法上面的代码就完全可以用了有兴趣的朋友可与笔者进一步交流其它XML应用以及程序设计模式JEE开发Rose UML建模等知识记住我的EMailnbDeveloper@hotmailcom