c# xml配置文件,c++写xml文件

  c# xml配置文件,c++写xml文件

  来源:3358 www.blogjava.net/wXB _ NUDT/archive/2008/05/27/203317 . html

  C中没有操作XML文件的标准库,所以大家需要使用自己熟悉的XML库来读写XML文件。XML的一个重要用途是作为程序的配置文件,存储着与程序运行相关的各种数据。本文总结了使用libxml2库编写xml配置文件的一些经验。最后,提供了一个封装的类CXMLConfig,并详细说明了它的功能、用法和注意事项。

  阅读本文所需的技术背景:

  信用证简单语法;

  L XML技术,XPATH技术;

  c编译器知识;

  本文的内容包括:

  l下载安装LIBXML2和ICONV;

  l第一个示例程序的编写、编译、链接和运行;

  使用XPATH读出多个配置项的值;

  XML配置文件类CXMLConfig;

  l将配置项写入XML文件;

  使用l CXMLConfig类的摘要;

  在阅读本文之前,最好先看一下我的上一篇博客C的XML编程经验——libxml2库使用指南,里面专门介绍了libxml 2库的使用。本文不会详细介绍libxml2的使用,而是重点介绍如何访问xml中的数据。

  本文的源代码是一个VC6项目,它包含三个子项目。地址在http://www.blogjava.net/Files/wxb_nudt/XMLConfigFile.rar.

  1.下载并安装LIBXML2和ICONV

  为了方便读者,这一段是从之前的博客里抄来的。

  Libxml2是一个C语言的xml库,可以简单方便地提供对XML文档的各种操作,支持XPATH查询和XSLT转换等一些功能。Libxml2的下载地址是http://xmlsoft.org/,该库的完整版本是开源的,有示例程序和文档。最好先下载这个库,因为可以查看里面的文档和例子。

  windows版本的下载地址是http://www.zlatkovic.com/libxml.en.html;该版本仅提供头文件、库文件和dll,但不包含源代码、示例程序和文档。文中只需要下载libxml2库、iconv库和zlib库(注意libxml2库依赖于iconv和zlib库,本文重点介绍libxml2和iconv,zlib不做介绍)。我用的版本是libxml2-2.6.30.win32.zip,zlib-1.2.3.win32.zip和iconv。

  编程时我们用的是windows版本的libxml2,zlib,iconv,解压到指定的文件夹,比如D:libxml2-2.6.30.win32,D:zlib-1.2.3.win32,D: iconv-1.9.2.win32,其实我们知道在windows下使用头文件,库文件,dll是不需要安装的,也不使用任何需要注册的组件或者数据库。只要告诉编译器和链接器这些资源的位置。

  注意:D:“iconv-1 . 9 . 2 . win32”bin应添加到path变量中;d:“zlib-1 . 2 . 3 . win32”bin;D:libxml2-2.6.30.win32bin,否则在执行过程中找不到。或者使用更简单的方法,将三个dll复制到system32目录中。

  有两种方法可以编译基于libxml2链接的程序。第一种方式是在VC环境下设置lib和include路径,添加libxml2.lib和iconv.lib在链接设置中;第二种是用编译器选项告诉编译器cl.exe头文件的位置,用链接器选项告诉链接器link.exe库文件的位置。同时在windows环境变量path中添加libxml2中bin文件夹的位置,以便在程序运行时可以找到该dll(或者复制到system32目录下)。

  2.你好,XML配置文件

  这一节的源代码位于HelloXml项目中,使用的Xml文件是Helloxml.xml

  在安装和配置了libxml2和iconv库之后,您可以编写一个简单的程序来读取xml中的数据。XML内容如下:

  ?xml版本=1.0 编码=GB2312 ?

  主要2008 05 26/主要

  使用libxml2库读取主节点中包含的内容。代码如下:

  XML char * load config file(const char * szConfigFilename,xmlChar*xszRel)

  xmlDocPtrdoc//定义解析文档指针

  xmlNodePtrcurNodePtr//定义节点指针

  doc=XML readfile(szConfigFilename, GB2312 ,XML _ PARSE _ RECOVER);//解析文件

  if(doc==NULL)

  {

  fprintf(stderr, Documentnotparsedsuccessfully n’);

  XML freedoc(doc);

  出口(1);

  }

  curNodePtr=xmlDocGetRootElement(doc);//确定文档的根元素

  /*检查以确保当前文档包含内容*/

  if(curNodePtr==NULL)

  {

  fprintf(stderr, empty document n );

  XML freedoc(doc);

  出口(1);

  }

  //读取xml文档中的内容,并将其赋给object属性

  xszRel=xmlnode getcontent(curNodePtr);

  XML freedoc(doc);

  returnxszRel

  intmain(intargc,char*argv[])

  xmlChar * xszContent=NULL

  xszContent=LoadConfigFile( . DebugHelloXml.xml ,xsz content);

  if(xszContent!=空)

  {

  cout HELLO,XML configfile . content= xsz content endl;

  XML free(xsz content);

  }

  return0

  在编译代码之前,需要注意的是,存储xml文档的地方不是项目文件夹,而是项目文件夹顶部的调试目录,编译和链接的目的文件夹被设置为项目文件夹顶部的调试目录。其次,在link选项中添加了libxml2.lib和iconv.lib。第三,在系统的path变量中指明了libxml2.dll、iconv.dll和zlib1.dll的路径(为了方便读者,我把三个dll都复制到了Debug目录下)。

  编译后运行程序,得到如下结果:

  你好,XML配置文件。content=20080526

  3.使用XPATH读取多个配置项的值

  这一节的源代码位于XPathConfig项目中,使用的xml文件是XPathConfig.xml

  在上面的例子中,为了便于理解,根节点中只存储一个值,而实际的配置文件中往往同时存储多个配置项的值。例子如下:

  主要的

  IP 127.0.0.1 /IP

  端口80/端口

  /main

  IP地址和端口值存储在Xml中。XPATH地址分别是/main/IP/和/main/Port/。当然,更复杂的XPATH值也可以用同样的方式处理。

  为了方便操作xml文档,我写了一组xml函数,位于Code_Conv.h和Code_Conv.cpp中,它们的函数如下:

  L openXmlFile,打开Xml文档并返回文档指针;

  L closeXmlFile关闭Xml文档;

  Getxmlstring,根据XPATH路径读取字符串;

  Getxmlint,根据XPATH路径读取整数值;

  为了处理中文和查询Xpath节点,我还编写了上述函数调用的四个函数:

  Code _ convert,从一个代码转换到另一个代码;

  L u2g,由UTF-8转换为GB2312编码;

  L g2u,由GB2312转换为UTF-8;

  Get _ nodeset,调用xpath查询节点集,成功返回xpath的对象指针,失败返回NULL。

  然后,主程序简化为:

  IP=127.0.0.1端口=80

  看上面的代码可以发现,整个主程序除了一个xmlDocPtr变量之外,几乎和libxml2库没有任何关系。再次可以发现,这个变量几乎出现在每一个自定义函数中。它代表一种状态,也可以称为属性。而那些自定义函数就可以称为函数。所以按照很多C专著的说法,属性函数=对象。055-79000说C和C最大的区别是C有最适合存储程序状态的位置,也就是对象的属性;而c则必须在很多函数中预留位置来保存这种状态。这句话正确得可怕!

  4.XML的配置文件类CXMLConfig

  这一节的源代码位于项目UseClass中,使用的xml文件是XPathConfig.xml

  于是就有了下面的CXMLConfig类定义:

  int code _ convert(char * from _ charset,char*to_charset,char*inbuf,intinlen,char*outbuf,into utlen);

  //UNICODE代码转换成GB2312代码

  //成功则返回一个动态分配的char*变量,使用后需要手动释放,失败则返回NULL。

  char * u2g(char * in buf);

  //GB2312代码转换成UNICODE代码

  //成功则返回一个动态分配的char*变量,使用后需要手动释放,失败则返回NULL。

  char * g2u(char * in buf);

  //调用xpath查询节点集合,成功返回xpath的对象指针,失败返回NULL。

  xmlXPathObjectPtrget _ nodeset(const XML char * XPath);

  私人:

  stringm _ strFilename

  xmlDocPtrm _ doc

  使用该类重写主程序可以使用户完全脱离libxml2的库环境,省略打开和关闭xml文件的步骤,因为这些任务都是在构造函数和析构函数中完成的。

  5.将配置项写入XML文件。

  这一节的源代码位于项目UseClass中,使用的xml文件仍然是XPathConfig.xml

  目前CxmlConfig类有打开xml文件,读取数据,关闭XML文件的功能。也缺少写数据的功能。写数据函数的算法也很简单:先把xml文件读入内存,然后通过xpath找到对应的节点,修改节点的内容。最后,将内存中的xml文件一次性写入硬盘。这里需要注意的一点是,如果硬盘在写入过程中断电或出现其他故障,会造成不可恢复的错误,所有数据都会丢失。为了防止出现这种情况,在写入之前也要进行数据备份。考虑到所有因素,将以下函数添加到CXMLConfig类中:

  WriteXmlString:将一个字符串写入xml文档的相应节点;

  WriteXmlInt:将整数写入xml文档的对应节点;

  SaveConfigFile:将内存中的xml文档写入硬盘;

  SaveBakConfigFile:将当前xml文档保存到bak文件中(即xml文档名加上_BAK。XML);

  LoadbakConfigFile:将Bak文件读入内存;

  注意,调用保存配置文件时,会自动调用saveConfigFile,将原始配置文件保存为备份文件。修改后的类如下:

  boolwriteXmlString(conststringstrValue,const char * szXpath);

  boolwriteXmlInt(constintiValue,const char * szXpath);

  boolsaveConfigFile();

  boolsaveBakConfigFile();

  boolloadBakConfigFile();

  私人:

  //代码转换:从一种代码到另一种代码

  int code _ convert(char * from _ charset,char*to_charset,char*inbuf,

  intinlen,char * outbuf,intoutlen);

  //UNICODE代码转换成GB2312代码

  char * u2g(char * in buf);

  //GB2312代码转换成UNICODE代码

  char * g2u(char * in buf);

  //调用xpath查询节点集合,成功返回xpath的对象指针,失败返回NULL。

  xmlXPathObjectPtrget _ nodeset(const XML char * XPath);

  //禁止复制构造函数和=操作

  CXMLConfig(constCXMLConfig

  CXMLConfig运算符=(constCXMLConfig

  私人:

  stringm _ strFilename

  xmlDocPtrm _ doc

  然后我们修改了主程序,主程序的功能是读取数据,修改数据,然后存储在配置文件中。主要程序如下:

  跑完之后,你会发现两个结果。第一个是配置文件XPathConfig.xml中的内容被修改了,第二个是原来的配置文件备份在XPathConfig_bak.xml中

  6.CXMLConfig类的使用摘要

  到目前为止,CXMLConfig类提供了读取和保存XML配置文件的便利功能。那么使用CXMLConfig需要哪些步骤呢?

  首先,正确安装libxml2和iconv库,包括头文件、lib文件和dll文件。注意,头文件主要是libxml2和iconv的头文件。lib文件有两个libxml2.lib和iconv.lib,而dll有三个,分别是libxml2.lib、iconv.lib和zlib1.dll。注意:如果安装不正确,就无法正确编译我的示例程序,但是它可以运行,因为我已经把所有的dll都包含在运行目录里了。

  第二,确保你理解你的xml配置文件的结构,并把它放在正确的位置;

  第三,一个CxmlConfig XML配置(.debug xpathconfig.xml )语句用于正确构造CxmlConfig对象,调用相应的方法操作XML文件。

  CXMLConfig类的使用说明:

  首先,注意xml文件必须使用节点来存储数据,而不是属性。如果属性用于保存数据,CXMLConfig类将无法正确读取其数据,当然也无法正确写入数据。如果您感兴趣,可以扩展CXMLConfig类来访问属性数据。其实很简单。

  第二,如果两个节点有相同的XPATH路径,例如

  主要的

  IP 127.0.0.1 /IP

  IP 127.0.0.2

  端口80/端口

  /main

  那么使用getXmlString只会得到第一个节点的内容。同样,在写入时,只会写入第一个节点。

  CXMLConfig类的使用环境:

  第一,使用节点存储数据;

  其次,节点的XPATH路径不同;

  第三,XML文件不能超过100M。

  总之,如果有更复杂的需求,请仔细研究libxml2或任何开源或商用的xml库。

  7.文末的话

  其实按照原来的计划,这个博客只是个开始,后面才是最精彩的部分。其内容是介绍如何把XML文件当作一个小数据库,把具有相同XPATH路径的键和值读入一个STD: map STD: String,STD: String,然后利用这个map在程序中方便地查找和访问某类数据。不过因为前面部分写的太详细,而且CXMLConfig类的引入也在逐渐完善,所以为了防止对主机角色的篡夺,这篇文章还是到此结束比较好。作为libxml2和C的入门文章,刚刚好!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • 设计一个简单的C#控制台应用程序,C#控制台程序,C# 创建控制台应用程序
  • 深入解析windows第8版,深入解析C#(第4版)
  • 数组代码,c# 数组操作,C# 数组实例介绍(图文)
  • 学会C#要多久,学会c#要多久,c#学习之30分钟学会XAML
  • 回溯法01背包问题c,回溯法求解01背包问题伪代码,C#使用回溯法解决背包问题实例分析
  • xml文件转义字符,xml转意字符,C# XML中的转义字符操作
  • winform 进度条控件,c# 进度条使用
  • winform 进度条控件,c# 进度条使用,C#使用winform实现进度条效果
  • winform backgroundworker,c# isbackground
  • winform backgroundworker,c# isbackground,C# BackgroundWorker用法详解
  • lua与c#交互,lua c#
  • lua与c#交互,lua c#,ToLua框架下C#与Lua代码的互调操作
  • linq c#,linq原理 c#
  • linq c#,linq原理 c#,c#中LINQ的基本用法实例
  • java decimal保留两位小数,sql中decimal函数保留2位小数,C#中decimal保留2位有效小数的实现方法
  • 留言与评论(共有 条评论)
       
    验证码: