- 实现ISAXContentHandler(startElement,characters,endElement)。
- 初始化ISAXXMLReader, 传入ISAXContentHandler。
- 解析XML文件。
<order id="ord123456"> <address> <zip>98052</zip> </address> </order>
#include <msxml2.h> #include <stdio.h> class SAXContentHandlerImpl : public ISAXContentHandler { public: SAXContentHandlerImpl(); virtual ~SAXContentHandlerImpl(); // This must be correctly implemented, if your handler must be a COM Object (in this example it does not) long __stdcall QueryInterface(const struct _GUID &,void ** ); unsigned long __stdcall AddRef(void); unsigned long __stdcall Release(void); virtual HRESULT STDMETHODCALLTYPE putDocumentLocator( /* [in] */ ISAXLocator __RPC_FAR *pLocator); virtual HRESULT STDMETHODCALLTYPE startDocument( void); virtual HRESULT STDMETHODCALLTYPE endDocument( void); virtual HRESULT STDMETHODCALLTYPE startPrefixMapping( /* [in] */ const wchar_t __RPC_FAR *pwchPrefix, /* [in] */ int cchPrefix, /* [in] */ const wchar_t __RPC_FAR *pwchUri, /* [in] */ int cchUri); virtual HRESULT STDMETHODCALLTYPE endPrefixMapping( /* [in] */ const wchar_t __RPC_FAR *pwchPrefix, /* [in] */ int cchPrefix); virtual HRESULT STDMETHODCALLTYPE startElement( /* [in] */ const wchar_t __RPC_FAR *pwchNamespaceUri, /* [in] */ int cchNamespaceUri, /* [in] */ const wchar_t __RPC_FAR *pwchLocalName, /* [in] */ int cchLocalName, /* [in] */ const wchar_t __RPC_FAR *pwchRawName, /* [in] */ int cchRawName, /* [in] */ ISAXAttributes __RPC_FAR *pAttributes); virtual HRESULT STDMETHODCALLTYPE endElement( /* [in] */ const wchar_t __RPC_FAR *pwchNamespaceUri, /* [in] */ int cchNamespaceUri, /* [in] */ const wchar_t __RPC_FAR *pwchLocalName, /* [in] */ int cchLocalName, /* [in] */ const wchar_t __RPC_FAR *pwchRawName, /* [in] */ int cchRawName); virtual HRESULT STDMETHODCALLTYPE characters( /* [in] */ const wchar_t __RPC_FAR *pwchChars, /* [in] */ int cchChars); virtual HRESULT STDMETHODCALLTYPE ignorableWhitespace( /* [in] */ const wchar_t __RPC_FAR *pwchChars, /* [in] */ int cchChars); virtual HRESULT STDMETHODCALLTYPE processingInstruction( /* [in] */ const wchar_t __RPC_FAR *pwchTarget, /* [in] */ int cchTarget, /* [in] */ const wchar_t __RPC_FAR *pwchData, /* [in] */ int cchData); virtual HRESULT STDMETHODCALLTYPE skippedEntity( /* [in] */ const wchar_t __RPC_FAR *pwchName, /* [in] */ int cchName); private: int indent; }; SAXContentHandlerImpl::SAXContentHandlerImpl() :indent(0) { } SAXContentHandlerImpl::~SAXContentHandlerImpl() { } HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::putDocumentLocator( /* [in] */ ISAXLocator __RPC_FAR *pLocator ) { return S_OK; } HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::startDocument() { wprintf(L"\nStart document!\n"); return S_OK; } HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::endDocument( void) { wprintf(L"\nEnd document!\n"); return S_OK; } HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::startPrefixMapping( /* [in] */ const wchar_t __RPC_FAR *pwchPrefix, /* [in] */ int cchPrefix, /* [in] */ const wchar_t __RPC_FAR *pwchUri, /* [in] */ int cchUri) { return S_OK; } HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::endPrefixMapping( /* [in] */ const wchar_t __RPC_FAR *pwchPrefix, /* [in] */ int cchPrefix) { return S_OK; } HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::startElement( /* [in] */ const wchar_t __RPC_FAR *pwchNamespaceUri, /* [in] */ int cchNamespaceUri, /* [in] */ const wchar_t __RPC_FAR *pwchLocalName, /* [in] */ int cchLocalName, /* [in] */ const wchar_t __RPC_FAR *pwchRawName, /* [in] */ int cchRawName, /* [in] */ ISAXAttributes __RPC_FAR *pAttributes) { HRESULT hr = S_OK; for(int i=0; i<indent; ++i) { wprintf(L"\t"); } ++indent; wprintf(L"<%s",pwchLocalName); int attributeNumber = 0; pAttributes->getLength(&attributeNumber); const wchar_t * attributeName = NULL; const wchar_t * valueName = NULL; int attributeNameLength = 0; int valueNameLength = 0;; wchar_t nameCache[64] = {0}; for ( int i=0; i<attributeNumber; i++ ) { pAttributes->getLocalName(i,&attributeName,&attributeNameLength); memset(nameCache, 0, 64); wcsncpy(nameCache, attributeName, attributeNameLength); wprintf(L" %s=", nameCache); pAttributes->getValue(i,&valueName,&valueNameLength); memset(nameCache, 0, 64); wcsncpy(nameCache, valueName, valueNameLength); wprintf(L"\"%s\"", nameCache); } printf(">\n"); return hr; } HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::endElement( /* [in] */ const wchar_t __RPC_FAR *pwchNamespaceUri, /* [in] */ int cchNamespaceUri, /* [in] */ const wchar_t __RPC_FAR *pwchLocalName, /* [in] */ int cchLocalName, /* [in] */ const wchar_t __RPC_FAR *pwchRawName, /* [in] */ int cchRawName) { --indent; for(int i=0; i<indent; ++i) { wprintf(L"\t"); } wchar_t nameCache[64] = {0}; wcsncpy(nameCache, pwchLocalName, cchLocalName); wprintf(L"</%s>\n", nameCache); return S_OK; } HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::characters( /* [in] */ const wchar_t __RPC_FAR *pwchChars, /* [in] */ int cchChars) { wchar_t nameCache[64] = {0}; wcsncpy(nameCache, pwchChars, cchChars); if(nameCache[0] == L' ' || nameCache[0]==L'\n') return S_OK; for(int i=0; i<indent-1; ++i) { wprintf(L"\t"); } wprintf(L"%s\n", nameCache); return S_OK; } HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::ignorableWhitespace( /* [in] */ const wchar_t __RPC_FAR *pwchChars, /* [in] */ int cchChars) { return S_OK; } HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::processingInstruction( /* [in] */ const wchar_t __RPC_FAR *pwchTarget, /* [in] */ int cchTarget, /* [in] */ const wchar_t __RPC_FAR *pwchData, /* [in] */ int cchData) { return S_OK; } HRESULT STDMETHODCALLTYPE SAXContentHandlerImpl::skippedEntity( /* [in] */ const wchar_t __RPC_FAR *pwchVal, /* [in] */ int cchVal) { return S_OK; } long __stdcall SAXContentHandlerImpl::QueryInterface(const struct _GUID &riid,void ** ppvObject) { return 0; } unsigned long __stdcall SAXContentHandlerImpl::AddRef() { return 0; } unsigned long __stdcall SAXContentHandlerImpl::Release() { return 0; } int main() { CoInitialize(NULL); ISAXXMLReader* pRdr = NULL; HRESULT hr = CoCreateInstance( __uuidof(SAXXMLReader), NULL, CLSCTX_ALL, __uuidof(ISAXXMLReader), (void **)&pRdr); if(!FAILED(hr)) { SAXContentHandlerImpl * pMc = new SAXContentHandlerImpl(); hr = pRdr->putContentHandler(pMc); const wchar_t* URL = L"C:\\sample.xml"; wprintf(L"\nParsing document: %s\n", URL); hr = pRdr->parseURL(URL); printf("\nParse result code: %08x\n\n",hr); pRdr->Release(); delete pMc; } else { printf("\nError %08X\n\n", hr); } CoUninitialize(); return 0; }