用C读取XML
QDomDocument读取和编辑xml文件

QDomDocument读取和编辑xml⽂件Qt中⼏种操作xml的⽅式流⽅式sax⽅式dom⽅式初学时,我常常采⽤流⽅式读取xml,该⽅式简单直观,容易理解。
之后遇到了需要修改xml并重新写回的情况,流⽅式就显得捉襟见肘了。
sax⽅式接触不多,从来没有在实际⽣产中使⽤过。
dom⽅式概念复杂,对于个⼈来说,⽂档也不是很清晰,导致我⼀直对这个⽅式不甚了解,最近下定决⼼好好研究⼀番,也算是⼤致清楚了个中“套路”,在此记录,以便今后查阅。
注意:如果你对QDomDocument没有任何了解,则不适合阅读此⽂章。
如果你在使⽤QDomDocumentde的过程中产⽣了疑惑,则此⽂可能对你产⽣帮助。
如有疏漏,还望指正。
QDomNode ? QDomElemet? QDomAttr?QDomText?初见QDomDocument时,我被这些东西搞得⼀头雾⽔。
直到我看到了某博客中这样⼀段话:QDom前缀的都是代表节点类型。
所以有,QDomElement代表⼀个Element节点,⽽QDomText代表⼀个Text节点。
QDomNode 类可以存储任意类型的节点。
如果想进⼀步处理⼀个节点,⾸先必须把它转化为正确的数据类型。
QDomNode调⽤toElement()以把它转化成QDomElement,然后调⽤tagName()来获得元素的标签名称。
如果节点不是Element类型,那么toElement()函数就返回⼀个空QDomElement对象和⼀个空标签。
我们对xml操作,⽆⾮对节点⽂本,节点属性进⾏操作,因此,我着重在这个基础上整理⼀下。
QDomNode 兼容所有节点类型。
这⾥只讨论QDomNode为QDomElemet的情况;此时读者⼼⾥⼀惊,难道,还有不是的情况?当然有!QDomNode QDomElemet举个简单例⼦你看!有如下xml<bookstore category="xml"><book category="CHILDREN"><title>Harry Potter</title><author>J K. Rowling</author><year>2005</year><price>29.99</price></book><!-- asdasd--><book category="WEB"><title>Learning XML</title><author>Erik T. Ray</author><year>2003</year><price>39.95</price></book><test>hello</test></bookstore>有如下代码:code 01QDomElement root = doc.documentElement();QDomNode node= root.firstChild();qDebug() << root.attributeNode("category").value();while(!node.isNull()){qDebug() << "xx";node = node.nextSibling();}结果会输出⼏个xx呢?代码做出如下更改code 02QDomElement root = doc.documentElement();QDomElement node= root.firstChildElement();qDebug() << root.attributeNode("category").value();while(!node.isNull()){qDebug() << "xx";node = node.nextSiblingElement();}结果会输出⼏个xx呢?答案分别是4和3!:smirk: :smirk:结论:注释是QDomNode⽽不是QDomElement到这⾥,⼤家应该就能明⽩两者的区别了。
closedxml使用手册

ClosedXML 是一个用于处理XML 文档的轻量级库,它提供了许多方便的功能,如数据解析、数据验证和XPath 查询等。
以下是ClosedXML 使用手册的简要概述:一、ClosedXML 简介ClosedXML 是一个用于处理XML 文档的库,它提供了许多方便的功能,如数据解析、数据验证和XPath 查询等。
它采用闭包语法,使得XML 文档的结构更加紧凑,易于维护。
二、ClosedXML 的使用方法1. 创建XML 文档对象:使用ClosedXML 创建一个XML 文档对象,可以使用以下代码:```csharpvar workbook = new XLWorkbook();```2. 添加XML 数据:使用ClosedXML 将数据添加到XML 文档中,可以使用以下代码:```csharpvar worksheet = workbook.Worksheets.Add("Sheet1");worksheet.Cell("A1").Value = "Name";worksheet.Cell("B1").Value = "Age";worksheet.Cell("A2").Value = "John";worksheet.Cell("B2").Value = 30;```3. 保存XML 文档:使用ClosedXML 将XML 数据保存到文件中,可以使用以下代码:```csharpworkbook.SaveAs(@"C:\example\example.xml");```4. 读取XML 数据:使用ClosedXML 从文件中读取XML 数据,可以使用以下代码:```csharpvar workbook = XLWorkbook.Open(@"C:\example\example.xml");var worksheet = workbook.Worksheets[0];string name = worksheet.Cell("A2").Value.ToString();int age = worksheet.Cell("B2").Value.ToInteger();```5. 进行XPath 查询:使用ClosedXML 进行XPath 查询以获取特定数据,可以使用以下代码:```csharpvar xmlDoc = new XDocument(worksheet.Range("A1:B3").ToXmlDocument());var names = from el in xmlDoc.Root.Elements("row") where (string)el.Element("Name") != "" select el.Element("Name").Value; foreach (var name in names) {Console.WriteLine(name);}```三、ClosedXML 的注意事项在使用ClosedXML 处理XML 数据时,需要注意以下几点:-需要确保所使用的ClosedXML 版本与您的开发环境兼容。
C语言读写XML文档:libmxml库初学笔记(Mini-XML)

C语⾔读写XML⽂档:libmxml库初学笔记(Mini-XML)使⽤XML存取数据很⽅便。
官⽹有详尽的英⽂⼿册,这⾥还找到了⼀份中⽂⼿册:这⾥只放⾃⼰学习时写的测试代码,有兴趣的同学可以做个参考。
#include<mxml.h>//创建xml⽂档//声明创建 xml树需要的 node节点mxml_node_t* xml; // xml格式标记mxml_node_t* keys_n; // 词汇库,unkey-词汇主键的⽗节点mxml_node_t* unikey_n; //⼀条词汇记录的基本单元,mark-词汇标签和 explain-词汇释义的⽗节点mxml_node_t* elem_n; //创建 mark explain 的节点//在内存中通过挂载node节点,构建 xml treexml=mxmlNewXML("1.0");//创建xml⽂档格式标记,必须,xml tree的根keys_n=mxmlNewElement(xml, "keys");//新节点,名为keys,挂载到 xmlunikey_n=mxmlNewElement(keys_n, "unikey");//新节点,名为unikey,挂载到 keysmxmlElementSetAttr(unikey_n, "word", "go alpha");//为unikey_n的节点设置属性:word="go alpha"elem_n=mxmlNewElement(unikey_n, "elem");//新节点,名为elem, 挂载到unikeymxmlElementSetAttr(elem_n, "element", "mark");//为elem_n的节点设置属性:element="mark"mxmlNewText(elem_n, 0, "AI");//为elem_n的节点新增⽂本,⽂本前的whitespace(空格)个数为0,内容为”AI”elem_n=mxmlNewElement(unikey_n, "elem");//新节点,名为elem, 挂载到unikeymxmlElementSetAttr(elem_n, "element", "explain");//为elem_n的节点设置属性:element="explain"mxmlNewText(elem_n, 0, "Google的AI程序");//为elem_n的节点新增⽂本,⽂本前的whitespace(空格)个数为0//将内存中创建的节点树写⼊⽂件FILE *fp = fopen("/Users/yaou/Area/tmp/xmltest-1.xml", "w");mxmlSaveFile(xml, fp, MXML_NO_CALLBACK);//关闭⽂件fclose(fp);//释放内存中的节点树mxmlDelete(xml);之后⼿动在新⽂件xmltext-1.xml ⾥添加⾥⼀些节点。
XML的创建、解析-C语言

XML的创建、解析-C语⾔ 前⾔:今天在做⼀个⼩项⽬时,客户要求的xml,跟现在有系统要求的不⼀样,所以要⾃⼰重新写函数⽀持返回,进⾏简单总结,希望对⼤家有所帮助。
⾸先,使⽤xml函数需要链上动态库libxml2,需要在电脑上安装libxml的开发包,安装⽅法如下: Ubuntu系统: sudo apt-get install libxml2-dev CentOS系统:yum install libxml2-devel 1. 创建XML⽂档(1)相关函数有许多,⽹上也有特别多的解释,⼤家可以百度⼀下,这⾥只是简单介绍⼀部分;创建⼀个XML⽂档⾮常简单,其流程如下:①⽤xmlNewDoc函数创建⼀个⽂档指针doc。
②⽤xmlNewNode函数创建⼀个节点指针root_node。
③⽤xmlDocSetRootElement将root_node设置为doc的根结点。
④给root_node添加⼀系列的⼦节点,并设置⼦节点的内容和属性。
⑤⽤xmlSaveFile将XML⽂档存⼊⽂件(⽤xmlDocDumpFormatMemoryEnc将XML存⼊内存)。
⑥⽤xmlFreeDoc关闭⽂档指针,并清除本⽂档中所有节点动态申请的内存。
有多种⽅式可以添加⼦节点,如可以⽤xmlNewTextChild直接添加⼀个⽂本⼦节点。
也可以先创建新节点,然后⽤xmlAddChild将新节点加⼊到上层节点中。
注:xmlSaveFile存⼊⽂件⽅便单独执⾏程序查看结果,⼀般项⽬⽤⽤xmlDocDumpFormatMemoryEnc将XML存⼊内存! (2)创建xml⽂件举例#include <stdio.h>#include <libxml/parser.h>#include <libxml/tree.h>int main(){xmlChar *result = NULL;int size = 0;xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0"); //定义⽂档和节点指针xmlNodePtr root_node = xmlNewNode(NULL,BAD_CAST "root");xmlDocSetRootElement(doc,root_node); //设置根节点//在根节点中直接创建节点xmlNewTextChild(root_node, NULL, BAD_CAST "newNode1", BAD_CAST "newNode1 content");xmlNewTextChild(root_node, NULL, BAD_CAST "newNode2", BAD_CAST "newNode2 content");xmlNewTextChild(root_node, NULL, BAD_CAST "newNode3", BAD_CAST "newNode3 content");//创建⼀个节点,设置其内容和属性,然后加⼊根结点xmlNodePtr node = xmlNewNode(NULL,BAD_CAST "node2");xmlNodePtr content = xmlNewText(BAD_CAST "NODE CONTENT");xmlAddChild(root_node,node);xmlAddChild(node,content);xmlNewProp(node,BAD_CAST "attribute",BAD_CAST "yes");//创建⼀个⼉⼦和孙⼦节点node = xmlNewNode(NULL, BAD_CAST "son");xmlAddChild(root_node,node);xmlNodePtr grandson = xmlNewNode(NULL, BAD_CAST "grandson");xmlAddChild(node,grandson);//xmlAddChild(grandson, xmlNewText(BAD_CAST "This is a grandson node"));xmlNodePtr congson = xmlNewNode(NULL, BAD_CAST "congson");xmlAddChild(grandson,congson);//存储xml⽂档//xmlKeepBlanksDefault(0);//xmlDocDumpFormatMemoryEnc(doc, &result, &size, "UTF-8", 1);int nRel = xmlSaveFile("CreateXml.xml",doc);if (nRel != -1){printf("⼀个xml⽂档被创建,写⼊%d个字节\n", nRel);}//释放⽂档内节点动态申请的内存xmlFreeDoc(doc);return1;} CentOS系统下⾯执⾏:gcc CreateXmlFile.c -o CreateXmlFile -I /usr/include/libxml2 -lxml2执⾏./CreateXmlFile,会⽣成⼀个XML⽂件CreatedXml.xml。
Android编程基础笔试题及答案

1、退出activity 对一些资源以及状态的操作保存,可以在生命周期的哪个函数中进行___A、onPause()B、onCreate()C、onResume()D、onStart()2、 Android 项目工程下面的assets 目录的作用是什么____A、放置应用到的图片资源。
Res/drawableB、主要放置一些文件资源,这些文件会被原封不动打包到apk 里面C、放置字符串,颜色,数组等常量数据res/valuesD、放置一些与UI 相应的布局文件,都是xml 文件res/layout3、下列不属于android布局的是___A、F r a m e L a y o u tB、L i n e a r L a y o u tC、BorderLayoutD、T a b l e L a y o u tE、R e l a t i v e L a y o u t4、Intent 的作用的是 ____A、intent是连接四大组件的纽带,可以实现界面间切换,可以包含动作和动作数据,B、是一段长的生命周期,没有用户界面的程序,可以保持应用在后台运行,而不会因为切换页面而消失 serviceC、实现应用程序间的数据共享 contentproviderD、处理一个应用程序整体性的工作5、下列哪个是AbsoluteLayout中特有的属性____A,android:layout_height B,android:layout_xC,android:layout_above D,android:layout_toRightOf6、RatingBar组件中不能用属性直接设置的是_____A,五角星个数B,当前分数C,分数的增量D,五角星的色彩7、在手机开发中常用的数据库是_____A,sqlLite B,Oracle C,Sql Server D,Db238、关于BroadcastReceiver的说法不正确的是____A, 是用来接收广播Intent的B,一个广播Intent只能被一个订阅了此广播的BroadcastReceiver所接收C, 对有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者D, 接收者声明的优先级别在<intent-filter>的android:priority属性中声明,数值越大优先级别越高9、使用MediaPlayer播放保存在sdcard上的mp3文件时____A,需要使用MediaPlayer.create方法创建MediaPlayerB,直接newMediaPlayer即可C,需要调用setDataSource方法设置文件源D,直接调用start方法,无需设置文件源10、在android中使用RadioButton时,要想实现互斥的选择需要用的组件是___A,ButtonGroup B, RadioButtons C,CheckBox D,RadioGroup11、在多个应用中读取共享存储数据时,需要用到的query方法,是哪个对象的方法?______A, ContentResolver B, ContentProvider C, Cursor D, SQLiteHelper12、DDMS中Log信息分为几个级别____A,3 B,4 C,5 D,613、能够自动完成输入内容的组件是___A,TextView B,EditText C,ImageView D,AutoCompleteTextView14、创建子菜单的方法是___A,add B,addSubMenu C,createSubMenu D,createMenu15、使用AIDL完成远程service方法调用下列说法不正确的是__A, aidl对应的接口名称不能与aidl文件名相同B, aidl的文件的内容类似java代码C, 创建一个Service(服务),在服务的onBind(Intent intent)方法中返回实现了aidl 接口的对象D, aidl对应的接口的方法前面不能加访问权限修饰符16、MediaPlayer播放资源前,需要调用哪个方法完成准备工作____A,setDataSource B,prepare C,begin D,pause17、处理菜单项单击事件的方法不包含____A, 使用onOptionsItemSelected(MenuItem item)响应B,使用onMenuItemSelected(int featureId ,MenuItem item) 响应C,使用onMenuItemClick(MenuItem item) 响应D,使用onCreateOptionsMenu(Menu menu)响应18、android中文件操作模式中表示只能被本应用使用,写入文件会覆盖的是___A, MODE_APPEND B,MODE_WORLD_READABLEC,MODE_WORLD_WRITEABLE D, MODE_PRIVATE19、进度条中哪个属性是设置进度条大小格式的_d_A,android:secondaryProgress B,android:progress C,android:max D,style 20、下列用以显示一系列图像的是_b_A,ImageView B,Gallery C,ImageSwitcher D,GridView21、表示下拉列表的组件是___A,Gallery B,Spinner C,GridView D,ListView22、关于AlertDialog的说法不正确的是__A,要想使用对话框首先要使用new关键字创建AlertDialog的实例B,对话框的显示需要调用show方法C,setPositiveButton方法是用来加确定按钮的D,setNegativeButton方法是用来加取消按钮的23、下列说法错误的是____A,Button是普通按钮组件,除此外还有其他的按钮组件B,TextView是显示文本的组件,TextView是EditText的父类C,EditText是编辑文本的组件,可以使用EditText输入特定的字符D,ImageView是显示图片的组件,可以通过设置显示局部图片24、关于android中播放视频的说法不对的是___A,可以使用SurfaceView组件播视频B,可以使用VideoView组件播视频C,VideoView组件可以控制播放的位置和大小D,VideoView播放视频的格式可以是3gp25、下列哪个是SqlLite下的命令__A,shell B,push C,.quit D,keytool26、D15EA1082(1分)下列关于如何使用Notification,不对的是__A,notification需要NotificatinManager来管理B,使用NotificationManager的notify方法显示notification消息C,在显示Notification时可以设置通知时的默认发声,震动等D,Notification中有方法可以清除消息27、下列关于open core说法不正确的是___A, Open core是Android多媒体框架的核心B, MediaPlayer是open Core中的一个核心类C, 所有在Android平台的音频、视频的采集以及播放等操作都是通过它来实现的D, 在实现开发中我们并不会过多地研究open core的实现,我们的Android为我们提供了上层的media api的开发使用28、上下文菜单与其他菜单不同的是____A,上下文菜单项上的单击事件可以使用onMenuItemSelected方法来响应B,上下文菜单必须注册到指定的view上才能显示C,上下文菜单的菜单项可以添加,可以删除D,上下文菜单的菜单项可以有子项29、拖动条组件是__A,RatingBar B,ProgressBar C,SeekBar D,ScrollBar30、读取文件内容的首要方法是___A,openFileOutput B,read C,write D,openFileInput31、关于隐式Intent正确的是__A, android中使用IntentFilter 来寻找与隐式Intent相关的对象B,通过组件的名称寻找与intent相关联的对象C, 隐式Intent更多用于在应用程序内部传递消息D, 一个声明了IntentFilter的组件只能响应隐式Intent请求32、D05MA2088(2分)多选框被选择事件通常用____A,setOnClickListener B,setOnCheckChangeListenerC, setOnMenuItemSelectedListener D,setOnCheckedListener33、D12EA1089(1分)自定义对话框时,将视图对象添加到当前对话框的方法是__A,setIcon B,setXML C,setLayout D,setView34、D09MA2090(2分)下列不属于service生命周期的方法是__A,onCreate B,onDestroy C,onStop D,onStart35、D09MA2091(2分)绑定Service的方法是___A,bindService B, startService C,onStart D,onBind二、多选题(共10题,共24分)36、 Intent 传递数据时,下列的数据类型哪些可以被传递____A、SerializableB、charsequenceC、ParcelableD、Bundle37、.android 数据存储与访问的方式一下说法正确的是:()A、文件B、数据库C、sharedpreferenceD、内容提供者E、网络38、下列可能会导致GC内存泄露的是:______A.数据库的cursor没有关闭B.构造adapter时,没有使用缓存contentviewC.衍生listview的优化问题-----减少创建view的对象,充分使用contentview,可以使用一静态类来优化处理getview的过程activity一般会重载一些方法用来维护其生命周期,下列不输于相关方法的是 D.使用sqlite数据库39、D09MA2095(2分) android 通过 startService 的方式开启服务, 关于 service生命周期的 onCreate()和 onStart() 说法正确的是 adA、当第一次启动的时候先后调用 onCreate()和 onStart()方法B、当第一次启动的时候只会调用 onCreate()方法C、如果 service 已经启动,将先后调用 onCreate()和 onStart()方法D、如果 service 已经启动,只会执行 onStart()方法,不在执行 onCreate()方法40、D02MB2096(2分)开发android程序需要的开发工具和开发包包括 abcdA, JDK B,Eclipse C,Android SDK D,ADT E,Raw41、D18MB2097(2分)下列属于补间动画相关类的是_acd__A,TranslateAnimation B,FrameAnimationC,RotateAnimation D, AlphaAnimation42、D13MB2098(2分)下列哪些 api 的操作需要声明权限 cdA、播放 mp3 文件B、读 SD 卡 (读 sd 卡状态)C、发短信D、访问网络43、 4.在 android 中使用 SQLiteOpenHelper 这个辅助类时,哪些操作可能生成一个数据库, abA、getWriteableDatabase()B、getReadableDatabase()C、getDatabase()D、getAbleDatabase()44、下列对SharePreferences存、取文件的说法中正确的是:abdA,属于移动存储解决方案 B,sharePreferences处理的就是key-value对C,读取xml文件的路径是/sdcard/shared_prefx D,信息的保存格式是xml45、NotificationManager中清除消息的方法是 bdA,destroy B,cancel C,clear D,cancelAll三、填空题:(共11题,15分)46、D11EC1102(1分)当启动一个Activity并且新的Activity执行完后需要返回到启动它的Activity来执行的回调函数是_____startActivityResult()47、D06EC1103(1分) android中输入日期的组件是__DatePicker ___48、D17EC1104(1分) AIDL的全称是__ Android interface definition language__49、D14MC2105 (2分)广播分为 ____无序广播和有序广播_______50、D06EC1106(1分) android中输入时间的组件是_TimePicker______51、D01EC1107(1分)Android应用的入口点是____Main___52、D19EC1108(1分) android中专门用于录音的组件是__MediaRecorder__53、D18MC2109(2分)动画中有一种___Frame__动画,通过顺序的播放排列好的图片来实现,类似电影。
Android考试题库

一、单选题(共33题,共62分)1、(2分) WebView中可以用来处理js中警示,确认等对话框的是(C)A。
WebSettingsB。
WebViewClientC。
WebChromeClientD。
WebViewChrome2、(2分) Android解析xml的方法中,将整个文件加载到内存中进行解析的是?(C)A、SAXB、PULLC、DOM D 、JSON3、(2分)以下属于调用摄像头硬件的权限的是:( A )A。
〈uses—permission android:name="android.permission。
CAMERA"/〉B。
〈uses-permission android:name=”android。
permission。
MOUNT_UNMOUNT_FILESYSTEMS”/〉C。
〈uses-permission android:name="android。
permission.WRITE_EXTERNAL_STORAGE”/> D。
<uses—permission android:name="android。
permission。
INTERNET"/〉4、(1分)使用Android系统进行拍照用到的类有:(D)A。
SurfaceView B。
SurfaceHolder C.Callback D。
Camera5、(2分)LocationManager获取位置信息的途径下列说法不正确的是(B )A, GPS定位更精确,缺点是只能在户外使用B, NETWORK通过基站和Wi— Fi信号来获取位置信息,速度较慢,耗电较少.C,获取用户位置信息,我们可以使用其中一个,也可以同时使用两个。
D, GPS定位耗电严重,并且返回用户位置信息的速度远不能满足用户需求.6、(2分) 在开发AppWidget窗口小部件时, 需要继承(D)类A,AppWidgetReceiverB,AppWidgetConfigureC,AppWidgetManagerD,AppWidgetProvider7、(4分)在AsyncTask中下列哪个方法是负责执行那些很耗时的后台计算工作的(C)A,runB,executeC,doInBackgroundD,onPostExecute8、(2分)如果希望自定义TabHost标题部分的显示内容需要使用下列哪个方法(B)finalTabHosttabHost = getTabHost();A,tabHost。
c读取配置文件的方法

c读取配置文件的方法在C语言中读取配置文件是非常常见的操作,它可以方便地管理程序的一些参数和选项,让程序更加灵活和易于维护。
下面是一些常见的方法:1. 使用标准库函数fopen和fscanf这是最常见的方法之一,使用标准库函数fopen和fscanf来逐行读取配置文件中的内容。
具体实现步骤如下:a. 使用fopen打开配置文件,获取文件指针。
b. 使用fscanf读取每一行的内容,根据具体的配置格式进行解析。
c. 关闭文件指针。
示例代码:FILE *fp;char buf[1024];int value;fp = fopen('config.ini', 'r');if (fp == NULL){printf('Cannot open config file.');return -1;}while (fgets(buf, sizeof(buf), fp) != NULL){if (sscanf(buf, 'key=%d', &value) == 1){// 解析成功,使用读取到的值进行后续操作printf('value=%d', value);}}fclose(fp);2. 使用ini配置文件解析库ini配置文件解析库是一个专门用来解析ini配置文件的库,它能够快速、简单地读取和修改ini文件中的配置项。
具体实现步骤如下:a. 下载并安装ini解析库。
b. 使用ini_parse函数读取配置文件。
c. 使用ini_get函数获取配置项的值。
示例代码:#include 'ini.h'int handler(void* user, const char* section, const char* name,const char* value)if (strcmp(section, 'config') == 0 && strcmp(name, 'key') == 0){// 获取配置项的值int* pvalue = (int*)user;*pvalue = atoi(value);}return 1;}int main(){int value;if (ini_parse('config.ini', handler, &value) < 0){printf('Cannot open config file.');return -1;}printf('value=%d', value);return 0;3. 使用XML配置文件解析库XML配置文件解析库是一个专门用来解析XML格式的配置文件的库,它能够解析复杂的XML文件,并且提供了灵活的配置项操作方式。
c#读写XML文件

System.Xml命名空间包含了一些最重要的XML类,其中最主要的类是和XML文档的读写操作相关的类。这些类中包括4个与读相关的类以及2个与写相关的类。它们分别是:XmlReader、XmlTextReader、 XmlValidatingReader、XmlNodeReader、XmlWriter以及 XmlTextWriter。本文将重点介绍这些类,因为它们是最基本也是最重要的类。
XmlNode类是一个非常重要的类,它代表了XML文档中的某个节点。该节点可以是XML文档的根节点,这样它就代表整个XML文档了。它是许多很有用的类的基类,这些类包括插入节点的类、删除节点的类、替换节点的类以及在XML文档中完成导航功能的类。同时,XmlNode类还为程序员提供了获取双亲节点、子节点、最后一个子节点、节点名称以及节点类型等的属性。它的三个最主要的子类包括: XmlDocument、XmlDataDocument以及XmlDocumentFragment。XmlDocument类代表了一个XML文档,它提供了载入和保存XML文档的方法和属性。这些方法包括了Load、LoadXml和Save等。同时,它还提供了添加特性(Attributes)、说明(Comments)、空间(Spaces)、元素(Elements)和新节点(New Nodes)等XML项的功能。XmlDocumentFragment类代表了一部分XML文档,它能被用来添加到其他的XML文档中。 XmlDataDocument类可以让程序员更好地完成和中的数据集对象之间的互操作。
using System;
using System.Xml;
namespace ReadXml
{
class Class1
{
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
用c读取XML文件可以将XML文件的树(只有一个顶层节点).于是理所当然的可以用树作为XML的一种存储结构.我将在这里用C++实现对简单的XML文件的解析.1.选择存储结构:树型数据结构有多种存储方式,我将用"孩子兄弟表示法",定义如下:typedef struct CSNode{int subNodes;string data;string name;struct CSNode *firstChild,*nextsibling,*parent;CSNode* operator=(CSNode cnode){this->data = cnode.data;this->firstChild = cnode.firstChild;this->name = ;this->nextsibling = cnode.nextsibling;this->subNodes = cnode.subNodes;return this;}}CSNode,*CSTree;2.定义一个ADT,提供操作的公共接口.取名为xmlclass xml{public:xml();xml(char *fileName);~xml();CSNode& CreateTree(); // 建立存储结构bool findData(const char *nodepos); // 查找节点值bool findData(const char *partent, const char *child,string *data); // 查找节点值bool readfile_(); // 读取xml源文件void allocate(); // 释放节点资源private:string _fileCope;char* _filename;CSNode *head;};3.具体实现#include "stdafx.h"#include "xmlCreate.h"#include "wstack.h"#include <algorithm>using namespace std;xml::xml(){}xml::xml(char *fileName) : _filename(fileName){head = new CSNode;}xml::~xml(){delete head;}CSNode& xml::CreateTree(){CSNode *p = new CSNode;CSNode *q = new CSNode;CSNode *s = new CSNode;wstack<string> nameStack;wstack<CSNode> nodeStack;string tmpstr;string name,tempname,rootName,headName;int noods = 0;bool subroot = true,next = false,poproot = false;unsigned short int enoods = 0;char ps;for (size_t i = 0; i < _fileCope.size(); ++i){ps = _fileCope[i];if (_fileCope[i] == ' ' || _fileCope[i] == '' || _fileCope[i] == '\t' || _fileCope[i] == 0x09 || _fileCope[i] == 0x0d)continue;if (_fileCope[i] == '<' && _fileCope[i+1] != '/') {s = new CSNode;s->subNodes = 0;enoods = 0;}else if (_fileCope[i] == '>') {enoods = 0;s->name = tmpstr;nameStack.push(tmpstr);tmpstr = "";noods++;size_t pn = i+1;char bug;while (pn < _fileCope.size()) {bug = _fileCope[pn];if (_fileCope[pn] == ' ' || _fileCope[pn] == '' || _fileCope[pn] == '\t' || _fileCope[pn] == 0x09 || _fileCope[pn] == 0x0d){pn++;continue;}else break;}if (_fileCope[pn] == '<') {subroot = true; // 向上解析}if(noods == 1){ // 保存根结点head = s;head->parent = NULL;head->nextsibling = NULL;p = head;headName = head->name;}else if (subroot) { // 还没有解析到叶子结点if (poproot) {p->nextsibling = s;p = p->nextsibling;poproot = false;}else{s->parent = p;p->firstChild = s;p = p->firstChild;}}else if (!subroot) { // 解析到叶子结点(第2个)s->parent = p;p->nextsibling = s;p->firstChild = NULL;p = p->nextsibling;}}else if (_fileCope[i] == '<' && _fileCope[i+1] == '/') { enoods++;//p->firstChild = NULL;if (subroot && enoods < 2){q = p->parent;rootName = q->name;subroot = false;}if(!subroot)q->subNodes++;string tname = nameStack.pop();i = i+tname.size()+2;if (tmpstr.size() > 0) {s->data = tmpstr;tmpstr = "";}else{subroot = true;next = false;}if (tname == rootName) {p->nextsibling = NULL;p->firstChild = NULL;p = q;poproot = true;}else if (tname == headName) {q->nextsibling = NULL;}}else{enoods = 0;if (_fileCope[i] != '/')tmpstr += _fileCope[i];}}delete s;return *head;}bool xml::readfile_(){ifstream infile(_filename,ios::binary);if (!infile) {//AfxMessageBox("Openfile failed!");return false;}bool lable = false;string _tfc(""),_lable("");char c;while(infile.get(c))_tfc += c;for (size_t i = 0; i < _tfc.size(); ++i){if (_tfc[i] == ' ' || _tfc[i] == '' || _tfc[i] == '\t' || _tfc[i] == 0x09 || _tfc[i] == 0x0d)continue;if (_tfc[i] == '<' && _tfc[i+1] == '?') {lable = true;}else if (_tfc[i] == '?' && _tfc[i+1] == '>') {lable = false;_lable += _tfc[i];_lable += _tfc[i+1];i += 2;continue;}else if (_tfc[i] == '<' && _tfc[i+1] == '!' && _tfc[i+2] == '-') {lable = true;}else if (_tfc[i] == '-' && _tfc[i+1] == '-' && _tfc[i+2] == '>'){lable = false;_lable += _tfc[i];_lable += _tfc[i+1];_lable += _tfc[i+2];i += 3;}if (lable) _lable += _tfc[i];else _fileCope += _tfc[i];}return true;}bool xml::findData(const char *nodeName){CSNode *p = head;string _nodeName = nodeName;return true;}bool xml::findData(const char *parent, const char *child,string *data){CSNode *p = head->firstChild;string _parent(""),_child("");bool isfound = false;while (p != NULL) {if (p->name == parent) {p = p->firstChild;while (p != NULL) {if (p->name == child) {*data = p->data;return true;}else p = p->nextsibling;}}else p = p->nextsibling;}return false;}void xml::allocate(){CSNode *p = head->firstChild; while (p != NULL) { CSNode *q = p->firstChild; while (q != NULL) { CSNode *s = q;q = q->nextsibling;if (s->name == "RecvPort") { cout << "addd" << endl;}delete s;}CSNode *m = p;p = p->nextsibling;delete m;}delete head;}。