BCB和XML

1、使用条件
C++ Builder对于XML处理主要封装在TXMLDocument组件中。该控件在Internet组中,图标为标识有XML的文档式样。如果没有该控件的话,你需要安装。TXMLDocument不是C++ Builder缺省安装的包,需要自己添加安装包。如果在C++ Builder目录的Bin目录下存在dclnet60.bpl文件,就直接安装就是,否则需要修改安装,以安装该组件包。
2、使用
  ①.基本操作
    a.使用控件方式加载XML文件:
      //加载XML文件    
      OpenDialog1->Filter = "XML(程序配置文件)|*.xml";   
      if (!OpenDialog1->Execute())
      {   
        return;   
      }   
   
      XMLDoc->LoadFromFile(OpenDialog1->FileName);   
      _di_IXMLNode node = XMLDoc->DocumentElement;   
      if (node == NULL)
      {   
        return;   
      }   
      //加载XML文件 
      OpenDialog1->Filter = "XML(程序配置文件)|*.xml"; 
      if (!OpenDialog1->Execute())
      { 
        return; 
      } 
      XMLDoc->LoadFromFile(OpenDialog1->FileName); 
      _di_IXMLNode node = XMLDoc->DocumentElement; 
      if (node == NULL)
      { 
        ShowMessage("不是合法的程序配置文件XML文件格式。"); 
        return; 
      }  
    b.使用控件方式保存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 + "文件成功");   
      }   
      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 + "文件成功"); 
      }        
  ②.读
    a.读取节点数据
      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();   
      }   
      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(); 
      }  
    b.读取节点属性
      //在格式描述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...   
      //在格式描述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);   
}   

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节中有描述。使用该组件的缩进方式直接
通过写入节点方式并不能得到格式化文档,当加载一个文件时可以自动格式化。一种简单的
格式化方式就是先保存好文件再读取一次,再保存就可以得到格式化的文档。
 
//声明:该代码源于网络,并做了些修改    
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;   
}   
 //声明:该代码源于网络,并做了些修改 
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获得该接口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值