- 实现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;
}