利用Expat库解析XML

如下是一个XML文件:sample.xml
<?xml version="1.0" encoding="utf-8"?>
<常用XML解析库>
    <库1>Xerces-C</库1>
    <库2>libxml2</库2>
    <库3>expat</库3>
    <库4>tinyxml</库4>
    <库5>msxml</库5>
</常用XML解析库>

#include <stdio.h>
#include <expat.h>
#include <Windows.h>

#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

class CXMLNodeContent
{
private:
	char* m_pNodeText;
	int m_BufferSize;
	int m_CurBufferSize;
public:
	CXMLNodeContent()
	{
		m_pNodeText = NULL;
		m_BufferSize = 0;
		m_CurBufferSize = 0;
	}
	~CXMLNodeContent()
	{
		if( m_pNodeText != NULL )
		{
			delete []m_pNodeText;
			m_pNodeText = NULL;
		}
		m_BufferSize = 0;
		m_CurBufferSize = 0;
	}
	int printNodeContent( const wchar_t* pText )
	{
		getNodeContent( pText );
		if( m_CurBufferSize == 1 )
			return 0;
		else
		{
			printf( "%s", m_pNodeText );
			return 1;
		}
	}

	int getBufferSize()
	{
		return m_CurBufferSize;
	}

	char* getNodeContent( const wchar_t* pText )
	{
		if( pText == NULL )
		{
			m_CurBufferSize = 0;
			return NULL;
		}
		int index = 0;
		m_CurBufferSize = WideCharToMultiByte(CP_ACP, 0 ,pText, -1 ,
			0 , 0, NULL, NULL);

		if( pText[0] == 10 )
		{
			while( pText[index] == 10 || pText[index] == 32 && index < m_CurBufferSize )
				index++;
			if( index == m_CurBufferSize )
			{
				m_CurBufferSize = 0;
				return NULL;
			}
		}

		if( m_CurBufferSize > m_BufferSize )
		{
			if( m_pNodeText == NULL )
			{
				m_pNodeText = new char[m_CurBufferSize];
				m_BufferSize = m_CurBufferSize;
			}
			else
			{
				delete []m_pNodeText;
				m_pNodeText = new char[m_CurBufferSize];
				m_BufferSize = m_CurBufferSize;
			}
		}

		WideCharToMultiByte(CP_ACP, 0 ,pText + index, -1 ,
			m_pNodeText , m_CurBufferSize, NULL, NULL);
		return m_pNodeText;
	}
};

static void XMLCALL
startElement(void *userData, const char *name, const char **atts)
{
  int i;
  int *depthPtr = (int *)userData;
  for (i = 0; i < *depthPtr; i++)
    putchar('\t');
  CXMLNodeContent nodeContent;
  int buf_length = MultiByteToWideChar( CP_UTF8, 0, name, -1, NULL, 0 );
  wchar_t* buffer = new wchar_t[buf_length];
  MultiByteToWideChar( CP_UTF8, 0, name, -1, buffer, buf_length );
  nodeContent.printNodeContent( buffer );
  putchar('\n');
  delete []buffer;
  *depthPtr += 1;
}

static void XMLCALL
endElement(void *userData, const char *name)
{
  int *depthPtr = (int *)userData;
  *depthPtr -= 1;
}

int
main(int argc, char *argv[])
{
  char buf[BUFSIZ];
  XML_Parser parser = XML_ParserCreate(NULL);
  FILE* p = fopen( "sample.xml", "rb" );
  int done;
  int depth = 0;
  XML_SetUserData(parser, &depth);
  
  XML_SetElementHandler(parser, startElement, endElement);
  do {
    int len = (int)fread(buf, 1, sizeof(buf), p);
    done = len < sizeof(buf);
    if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR) {
      fprintf(stderr,
              "%s at line %" XML_FMT_INT_MOD "u\n",
              XML_ErrorString(XML_GetErrorCode(parser)),
              XML_GetCurrentLineNumber(parser));
      return 1;
    }
  } while (!done);
  fclose( p );
  XML_ParserFree(parser);
  return 0;
}
原文地址:https://www.cnblogs.com/LinuxHunter/p/1890710.html