Borland C++ Builder 6.0 XML处理总结
1、安装
C++ Builder对于XML处理主要封装在TXMLDocument组件中,该组件是Internet组件的一部分。
如果在安装包有已经有Borland Internet Components组件,那表示已经可以使用
TXMLDocument控件了。该控件在Internet控制卡中,笔者的在最后一个,图标为标识有XML
的文档式样。如果没有该控件的话,你需要安装。
TXMLDocument不是C++ Builder缺省安装的包,需要自己添加安装包。如果在C++ Builder
目录的Bin目录下存在dclnet60.bpl文件,就直接安装就是,否则需要修改安装,以安装该
组件包。
2、使用
2.1 基本操作
2.1.1 使用控件方式加载XML文件示例:
//加载XML文件 OpenDialog1->Filter = "XML(程序配置文件)|*.xml"; if (!OpenDialog1->Execute()){ return; } XMLDoc->LoadFromFile(OpenDialog1->FileName); _di_IXMLNode node = XMLDoc->DocumentElement; if (node == NULL){ ShowMessage("不是合法的程序配置文件XML文件格式。"); return; }
2.1.2 使用控件方式保存XML文件示例:
SaveDialog1->FileName = FDevTypeName + ".xml"; SaveDialog1->Filter = "XML(程序配置文件)|*.xml"; if (SaveDialog1->Execute()){ XMLDoc->Active=true; XMLDoc->Version = "1.0"; XMLDoc->Encoding = "GB2312"; XMLDoc->Options << doNodeAutoIndent; //建立文档主元素 XMLDoc->DocumentElement = XMLDoc->CreateElement("Config", ""); XMLDoc->DocumentElement->SetAttribute("DevType", FDevTypeName); //从UI更新XML数据 UpdateXMLDataFromUI(XMLDoc->DocumentElement); //格式化XML XMLDoc->LoadFromXML(formatXMLDoc(XMLDoc, 1)); //保存XML文件 XMLDoc->SaveToFile(SaveDialog1->FileName); ShowMessage("保存配置"+ SaveDialog1->FileName + "文件成功"); }
2.2 读
2.2.1 读取节点数据
AnsiString GetNodeData(_di_IXMLNode panode, AnsiString nodename, AnsiString defaultvalue) { //取得子节点列表 _di_IXMLNodeList nodes = panode->ChildNodes; //从子节点列表查找节点 _di_IXMLNode node = nodes->FindNode(nodename); if (node == NULL){ return defaultvalue; } //从节点取得数据 return node->GetText(); }
2.2.1 读取节点属性
//在格式描述XML文件中定位列描述 nodename = "grid"; _di_IXMLNode uinode = XMLUI->DocumentElement; _di_IXMLNodeList uinodelst = uinode->ChildNodes; uinode = uinodelst->FindNode(nodename); uinodelst = uinode->ChildNodes; for (jdx = 0; jdx < uinodelst->Count; jdx++){ //取得当前列在表格中的位置 colname = uinodelst->Nodes[jdx]->GetText(); //设置列头 colheader = colname + "(" + uinodelst->Nodes[jdx]->GetAttribute("length") ; //根据类型设置表格列类型,用于编辑 //取得节点属性示例 if (AnsiString(uinodelst->Nodes[jdx]->GetAttribute("type")) == AnsiString("Hex")){ colheader += ", Hex"; }else if (AnsiString(uinodelst->Nodes[jdx]->GetAttribute("type")) == AnsiString("DevType")){ }else if (AnsiString(uinodelst->Nodes[jdx]->GetAttribute("type")) == AnsiString("Baud")){ }else if (AnsiString(uinodelst->Nodes[jdx]->GetAttribute("type")) == AnsiString("Integer")){ colheader += ", Dec"; }else{ colheader += ", Dec"; } colheader += ")"; //...(省略) }//~for(jdx...
2.3 写
以下代码演示了如果添加子节点,以及设置属性,写XML文件在第1节点有所描述。
void UpdateNodeData(_di_IXMLNode panode, AnsiString nodename, AnsiString value, AnsiString friendlyname) { _di_IXMLNodeList nodes = panode->ChildNodes; _di_IXMLNode node = nodes->FindNode(nodename); if (node == NULL){ //添加子节点 node = panode->AddChild(nodename); //设置属性 node->SetAttribute("FriendlyName", friendlyname); } //改变节点数据 node->SetText(value); }
2.4 格式化XML
以上代码为格式化XML,调用方式在写XML在2.1.2节中有描述。使用该组件的缩进方式直接
通过写入节点方式并不能得到格式化文档,当加载一个文件时可以自动格式化。一种简单的
格式化方式就是先保存好文件再读取一次,再保存就可以得到格式化的文档。
//声明:该代码源于网络,并做了些修改 //--------------------------------------------------------------------------- //格式化XML文档 //--------------------------------------------------------------------------- AnsiString formatXMLDoc(TXMLDocument* doc, int indent) { AnsiString sRes; int i; sRes = "<?xml version=/"" + doc->Version + "/" encoding=/"" + doc->Encoding + "/"?>/r/n"; sRes += "<" + doc->DocumentElement->NodeName; for (i = 0; i < doc->DocumentElement->AttributeNodes->Count; i++) { sRes += " " + doc->DocumentElement->AttributeNodes->Nodes[i]->NodeName + "=/"" + doc->DocumentElement->AttributeNodes->Nodes[i]->NodeValue + "/""; } sRes += ">/r/n"; for (i = 0; i < doc->DocumentElement->ChildNodes->Count; ++i){ sRes += formatXMLNode(doc->DocumentElement->ChildNodes->Nodes[i], indent); } sRes += "</" + doc->DocumentElement->NodeName + ">/r/n"; return sRes; } AnsiString formatXMLNode(_di_IXMLNode element, int indent) { AnsiString sBlank = ""; AnsiString sRes = ""; int i; for (i = 0; i < indent; ++i){ sBlank += " "; } if (element->NodeType == ELEMENT_NODE && element->ChildNodes && element->ChildNodes->Count > 0 && element->ChildNodes->Nodes[0]->NodeType != TEXT_NODE) { sRes = sBlank + '<'+element->NodeName; for (i = 0; i < element->AttributeNodes->Count; i++) { sRes += " " + element->AttributeNodes->Nodes[i]->NodeName + "=/"" + element->AttributeNodes->Nodes[i]->NodeValue + "/""; } sRes += ">/r/n"; indent++; for (i = 0; i < element->ChildNodes->Count; i++) { sRes += formatXMLNode(element->ChildNodes->Nodes[i], indent); } sRes += sBlank + "</" + element->NodeName + ">/r/n"; } else if (element->NodeType != PROCESSING_INSTRUCTION_NODE) { sRes += sBlank + element->XML + "/r/n"; } return sRes; }
3、注意事项
以上描述的方式是通过XML控件方式来操作XML文档。在使用对象方式操作XML文件时,需要注意一些问题。
在加载一个文件时,不需要创建一个TXMLDocument对象(TXMLDocument *myxml = new TXMLDocument()),
而是使用_di_IXMLDocument接口。从文件加载XML文件是使用LoadXMLDocument来获得该接口的实例。操作
一个空的XML文档并开始写时也是使用该接口NewXMLDocument获得该接口。