特点:C++编写的,一个.h,一个.cpp,绿色小巧,直接加入工程源码编译,只支持MFC。
<?xml version="1.0" encoding="utf-8"?>
<root>
<update ver="1.2.0" pkg="setup.exe" force="1"/>
<update ver="1.1.1" pkg="setup.exe" force="0"/>
<update ver="1.1.0" pkg="setup.exe" force="0"/>
</root>
CMarkup markup;
bool bSucceed = markup.Load(szFile);
if (bSucceed)
{
bSucceed = markup.FindElem();
if (bSucceed)
{
markup.IntoElem();
bSucceed = markup.FindElem(_T("update"));
if (bSucceed)
{
_tcsncpy_s(param.version, markup.GetAttrib(_T("ver")), sizeof(param.version));
_tcsncpy_s(param.pkgname, markup.GetAttrib(_T("pkg")), sizeof(param.pkgname));
if (markup.GetAttrib(_T("force")).Compare(_T("1")) == 0)
param.forceUpdate = true;
}
else
{
LOG_ERROR(_T("配置文件%s 没有update节点!"), szFile);
}
}
else
{
LOG_ERROR(_T("配置文件%s 没有根节点!"), szFile);
}
}
else
{
LOG_ERROR(_T("配置文件%s 错误!"), szFile);
}
GetAttrib获取节点属性,GetData获取节点值。二、tinyxml2 下载:
特点:也是两个文件,小巧灵活,且跨平台。
读xml:
tinyxml2::XMLDocument doc;
try
{
if(doc.LoadFile(szFile) == 0)
{
tinyxml2::XMLElement* pRootEle = doc.RootElement();
for(auto pInstrumentEle = pRootEle->FirstChildElement(); pInstrumentEle != nullptr; pInstrumentEle = pInstrumentEle->NextSiblingElement())
{
_tcsncpy_s(param.version, pInstrumentEle->Attribute(_T("ver")), sizeof(param.version));
_tcsncpy_s(param.pkgname, pInstrumentEle->Attribute(_T("pkg")), sizeof(param.pkgname));
if (pInstrumentEle->IntAttribute(_T("force")).Compare(_T("1")) == 0)
param.forceUpdate = true;
}
}
}
catch(...)
{
LOG_ERROR(_T("配置文件%s 读取异常!"), szFile);
}
写xml:
tinyxml2::XMLDocument doc;
doc.LinkEndChild(doc.NewDeclaration("xml version=\"1.0\" encoding=\"UTF-8\""));
tinyxml2::XMLElement* pRootEle = doc.NewElement(_T("root"));
doc.LinkEndChild(pRootEle);
tinyxml2::XMLElement* pNewEle;
pNewEle = doc.NewElement(_T("update"));
pNewEle->SetAttribute(_T("ver"), _T("1.3"));
pNewEle->SetAttribute(_T("pkg"), _T("setup.exe"));
pNewEle->SetAttribute(_T("force"), _T("0"));
doc.SaveFile("test.xml");
三、MSXML:
特点:Windows自带COM解析库,支持xsd规范(即xml不符合xsd规定格式,则加载失败报错)。
#import <msxml6.dll> named_guids
...
BOOL ParseXml::LoadXmlFile(MSXML2::IXMLDOMDocument2Ptr &pDoc, LPCTSTR lpXmlFile)
{
// create schema
MSXML2::IXMLDOMSchemaCollectionPtr pSchema;
pSchema.CreateInstance(MSXML2::CLSID_XMLSchemaCache60);
try
{
// adding <namespace, schema> pair to collection
pSchema->add(_bstr_t(g_schema_namespace), _variant_t(m_pXsdFile));
}
catch (_com_error &e)
{
flog(LOGERROR, _F("ParseXml::LoadXmlFile"),
_T("Add schema: '%s' to SchemaCollection Error!(ErrorCode = 0x%08xl, Reason: %s)"),
m_pXsdFile, e.Error(), (LPCTSTR)e.Description());
return FALSE;
}
// create DOM object
pDoc.CreateInstance(MSXML2::CLSID_DOMDocument60);
// set attributes
pDoc->async = VARIANT_FALSE; // not permit asynchronous download
pDoc->validateOnParse = VARIANT_TRUE; // validates during parsing
pDoc->setProperty(_bstr_t("SelectionNamespaces"), _variant_t(g_select_namespaces)); // set select namespaces
// associate xml and schema
pDoc->schemas = pSchema.GetInterfacePtr();
// load xml file
VARIANT_BOOL vbRet = pDoc->load(_variant_t(lpXmlFile));
if (vbRet == VARIANT_FALSE)
{
MSXML2::IXMLDOMParseErrorPtr pError = pDoc->parseError;
flog(LOGERROR, _F("ParseXml::LoadXmlFile"),
_T("Load xml file: '%s' Error!(code=%ld, reason=%s, url=%s, srcText=%s, line=%ld)"),
lpXmlFile, pError->errorCode, (LPCTSTR)pError->reason, (LPCTSTR)pError->url,
(LPCTSTR)pError->srcText, pError->line);
return FALSE;
}
else
{
flog(LOGINFO, _F("ParseXml::LoadXmlFile"),
_T("Load xml file: '%s' Success!"), lpXmlFile);
return TRUE;
}
}
四、expat 官网:
特点:Expat是一个用C语言开发的、用来解析XML文档的开发库,它最初是开源的、Mozilla 项目下的一个XML解析器。Expat是一个面向流的解析器。您注册的解析器回调(或handler)功能,然后开始搜索它的文档。当解析器识别该文件的指定的位置,它会调用该部分相应的处理程序(如果您已经注册的一个)。该文件被输送到解析器,会被分割成多个片断,并分段装到内存中。因此expat可以解析那些巨大的文件。
请下载源码自行编译,源码自带example:
/*****************************************************************
* outline.c
*
* Copyright 1999, Clark Cooper
* All rights reserved.
*/
#include <stdio.h>
#include <expat.h>
#if defined(__amigaos__) && defined(__USE_INLINE__)
#include <proto/expat.h>
#endif
#ifdef XML_LARGE_SIZE
#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
#define XML_FMT_INT_MOD "I64"
#else
#define XML_FMT_INT_MOD "ll"
#endif
#else
#define XML_FMT_INT_MOD "l"
#endif
#define BUFFSIZE 8192
char Buff[BUFFSIZE];
int Depth;
static void XMLCALL
start(void *data, const char *el, const char **attr)
{
int i;
for (i = 0; i < Depth; i++)
printf(" ");
printf("%s", el);
for (i = 0; attr[i]; i += 2) {
printf(" %s='%s'", attr[i], attr[i + 1]);
}
printf("\n");
Depth++;
}
static void XMLCALL
end(void *data, const char *el)
{
Depth--;
}
int
main(int argc, char *argv[])
{
XML_Parser p = XML_ParserCreate(NULL);
if (! p) {
fprintf(stderr, "Couldn't allocate memory for parser\n");
exit(-1);
}
XML_SetElementHandler(p, start, end);
for (;;) {
int done;
int len;
len = (int)fread(Buff, 1, BUFFSIZE, stdin);
if (ferror(stdin)) {
fprintf(stderr, "Read error\n");
exit(-1);
}
done = feof(stdin);
if (XML_Parse(p, Buff, len, done) == XML_STATUS_ERROR) {
fprintf(stderr, "Parse error at line %" XML_FMT_INT_MOD "u:\n%s\n",
XML_GetCurrentLineNumber(p),
XML_ErrorString(XML_GetErrorCode(p)));
exit(-1);
}
if (done)
break;
}
XML_ParserFree(p);
return 0;
}
五、boost库的property_tree组件
《boost的property_tree组件》
六、Poco xml
《Poco c++ Library 之xml 的使用》
(持续整理...任何疑问点此提问)