引言:记录下对XML解析的学习
解析方法:
1、直接加载文本的方式
2、使用微软自带com组件msxml.dll
3、使用正则表达式解析
4、使用第三方库tinyxml解析
XML解析示例(word.xml)
<WORD>
<line rsidR="000060E0" rsidRDefault="00B30946">
<font>宋体</font>
<size>9</size>
</line>
<line rsidR="00E702F8" rsidRDefault="00E702F8">
<font>楷书</font>
<size>12</size>
</line>
</WORD>
1、直接加载文本的方式
将我们所需要的XML文件当做普通文件,然后将其读入内存,通过普通字符串的匹配来解析XML文件。适用于解析一些不规范的XML文件
void XmlBySelf()
{
//打开一个word.xml文档
HANDLE hfile = CreateFileA("word.xml", GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if (hfile == INVALID_HANDLE_VALUE)
printf("open file fail!\n");
DWORD dwSize;
DWORD dwRead;
dwSize = GetFileSize(hfile, NULL);//获取文件大小
char* buf = new char[dwSize + 1];//动态申请一片内存
memset(buf, 0, dwSize + 1);
ReadFile(hfile, buf, dwSize, &dwRead, NULL);//把文件内容读取到内存中
char* lpStart; // 指向文件的开始位置
char* lpEnd; // 指向文件的末尾
lpStart = buf;
lpEnd = buf + dwSize;
char begin[] = "<font>"; // 检索的节点
char end[] = "</font>";
for (;lpStart < lpEnd; lpStart++)
{
if (memcmp(lpStart,begin, strlen(begin)) == 0)
{
lpStart += strlen(begin);
break;
}
}
char * lpStart2 = lpStart;
for (; lpStart2 < lpEnd; lpStart2++)
{
if (memcmp(lpStart2, end, strlen(end)) == 0)
{
*lpStart2 = 0;
break;
}
}
printf("%s", lpStart);
delete[] buf;
return;
}
运行结果:宋体
示例中只查找了第一个要找的font节点
2、使用微软自带com组件msxml.dll
COM组件MsXml6.dll(在C:\WINDOWS\system32\msxml6.dll目录下)解析。
资料http://blog.csdn.net/qq2399431200/article/details/17583171
3、使用正则表达式解析
#include <regex>//这个是正则表达式的头文件
#include <string>
using namespace std;
void XmlByRegex()
{
//打开一个本地文档
HANDLE hfile = CreateFileA("word.xml", GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if (hfile == INVALID_HANDLE_VALUE)
{
printf("打开文件失败!");
}
DWORD dwSize;
DWORD dwRead;
//获取文件大小
dwSize = GetFileSize(hfile, NULL);
//动态申请一片内存
char* buf = new char[dwSize + 1];
memset(buf, 0, dwSize + 1);
//把文件内容读取到内存中
ReadFile(hfile, buf, dwSize, &dwRead, NULL);
string str = "<size>.*(?=</size>)";
regex_constants::syntax_option_type f1 = regex_constants::icase;//取消大小写敏感
regex pattern(str, f1);//正则表达式搜索的式子
string sBuf = buf;
tr1::sregex_token_iterator it(sBuf.begin(), sBuf.end(), pattern);
tr1::sregex_token_iterator end;
for (;it != end; ++it)
{
printf("%s\n", it->str().c_str());
}
delete[] buf;
return;
}
4、使用第三方库tinyxml解析
tinyxml资源:http://pan.baidu.com/s/1nu9C1rr
资料:http://blog.csdn.net/tennysonsky/article/details/48630005
#include "tinyxml.hpp"
void XmlByTinyxml()
{
TiXmlDocument doc("word.xml");
bool loadResult = doc.LoadFile();
if (!loadResult)
{
printf("Load XML file error\n");
return;
}
//如果加载成功了,继续,获取根节点
TiXmlElement * root = doc.RootElement();
for (TiXmlNode * item = root->FirstChild("line"); item; item = item->NextSibling("line"))
{
const char * rsidR = item->ToElement()->Attribute("rsidR");
const char * rsidRDefault = item->ToElement()->Attribute("rsidRDefault");
printf("rsidR: - %s\trsidRDefault - %s\t", rsidR, rsidRDefault);
TiXmlNode * child = item->FirstChild();
const char * font = child->ToElement()->GetText();
printf("name - %s\t", font);
child = child->NextSiblingElement();
const char * size = child->ToElement()->GetText();
printf("\tsize: [ %s ]\n", size);
printf("-------------------------\n\n");
}
return;
}
void WriteXml()//使用 tinyxml 写一个XML文件
{
//创建一个文档对象
TiXmlDocument* myDocument = new TiXmlDocument();
//创建一个根节点
TiXmlElement* RootElement = new TiXmlElement("ZY");
//把根节点加入到文档里面
myDocument->LinkEndChild(RootElement);
//创建一个子节点,加入到根节点中
TiXmlElement* LikeInfo = new TiXmlElement("MYLIKE study");
RootElement->LinkEndChild(LikeInfo);
TiXmlElement* LoveInfo = new TiXmlElement("MYLOVE is");
RootElement->LinkEndChild(LoveInfo);
myDocument->SaveFile("./MYLikeLove.xml");
return;
}