本文使用的是libxml库进行遍历xml文件,读取想要的属性和文本信息。
首先引用所需的头文件和添加库。
#include <libxml\parser.h>
#pragma comment(lib,"iconv.lib");
#pragma comment(lib,"libxml2.lib");
//记得一共有三个库,但是我目前只包含了这两个
/* xml的结构类似树,所以使用的时候有点类似 */
我的程序比较繁琐而且欠缺优化,仅仅目前可用,占用内存以及系统开销都挺大。
ReadFileGetAllNeeds()
{
xmlKeepBlankDefault(0);
//这句话是去掉每个Node之间的空白Node否则会出现系统填充的空白Node(个人理解)
//定义待解析的文档指针。
xmlNodePtr pDoc = NULL;
//定义了根节点的指针
xmlNodePtr RootNode = NULL;
char szDocName[] = "E:\\Demo.xml";
//打开指定的文件
pDoc = xmlReadFile(szDocName. "UTF-8",XML_PARSE_RECOVER);
//按照指定的编码格式解析文件
if(NULL == pDoc)
{
cout<<"Error Open File"<<endl;
return -1;
}
RootNode = xmlDocGetRootElement(pDoc);
//获取根节点
if(NULL == RootNode)
{
cout<<"Is Empty File"<<endl;
return -2;
}
//判断Root是否正确,且是我们需要的,这里是"Events"
if(xmlStrcmp(curNode->name,BAD_CAST"Events"))
{
cout<<"Error RootNode"<<endl;
return -3;
}
//由于获取的结构内信息比较多,这里就不一一列举,可以进入调试模式,在监视窗口进行查看。
cout<<"RootNode is :"<< RootNode->name <<endl;
//下面遍历所有的节点,当前Xml文件Root节点不需要信息,所以不处理
xmlNodePtr pTravelXml = RootNode->children;
//每个chidren都是一个孩子节点,孩子节点下还可能会有孩子节点
//根据Xml文件的格式,和所需求的内容不同,读取或过滤的方式不同
//这个循环体对所有的儿子节点进行遍历,在内部可以对孙子或者更深的进行操作
while(pTravelXml)
{ pFind = pTravelXml;
while(pFind) //对当前儿子节点进行遍历
{
if (!xmlStrcmp(pFind->name,BAD_CAST"Execution"))
{
//找到了"Execution"节点
//<Execution ProcessId=0xac3 ...>
//获取属性ProcessID信息。
char* szProcessId = (char*)xmlGetProp(pFind,BAD_CAST "ProcessID");
cout << szProcessId << endl;
xmlFree(szProcessId);
//并非智能指针需要手动进行释放,所有的都是
szProcessId = NULL;
//获取文本信息
//<Execution ...> Content </>
char* szBtye = (char*)xmlNodeGetContent(pFind);
//操作之后进行释放
xmlFree(szBtye);
szBtye = NULL;
}
pFind = pFind->next;
}
pTravelXml = pTravelXml->next;
//如果当前结点存在兄弟节点,则next就到了兄弟节点
}
}