C++ 读写xml方法整理(持续更新)

来源:清泛原创     2016-04-13 10:11:36    人气:     我有话说( 0 人参与)

清泛网(www.tsingfun.com):c++读写xml的方法可谓是五花八门,太多了,这里对常用的几种做一个总结,附demo。

1、Markup 下载
特点: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 的使用


(持续整理...任何疑问点此提问

c++ 读写xml

注:本文为本站或本站会员原创优质内容,版权属于原作者及清泛网所有,
欢迎转载,转载时须注明版权并添加来源链接,谢谢合作! (编辑:admin)