Listing 3: Major functions of the CompositeContentHandler<Data, Functor> class.
// only partial listing template <class Data, class Functor> class CompositeContentHandler : public BaseContentHandler { BaseContentHandler* m_pDocumentHandler; Functor* m_pFunctor; Data m_Data; vector<ContentHandlerPtr> m_ChildHandlers; public: CompositeContentHandler(const XmlString& name, BaseContentHandler* pDocumentHandler, Functor* pFunctor) : BaseContentHandler(name), m_pDocumentHandler(pDocumentHandler), m_pFunctor(pFunctor) { BaseContentHandler* pTempHandler; const XmlBindingEntry* pEntry = m_Data.GetXmlBindingEntries(); while(pEntry->eDataType != eXML_EMPTY) { pTempHandler = CreateHandler(pDocumentHandler, pEntry); m_ChildHandlers.push_back(pTempHandler); m_pDocumentHandler->AddContentHandler(pTempHandler); ++pEntry; } m_pDocumentHandler->AddContentHandler(this); } virtual HRESULT STDMETHODCALLTYPE endElement( /* [in] */ wchar_t __RPC_FAR *pwchNamespaceUri, /* [in] */ int cchNamespaceUri, /* [in] */ wchar_t __RPC_FAR *pwchLocalName, /* [in] */ int cchLocalName, /* [in] */ wchar_t __RPC_FAR *pwchRawName, /* [in] */ int cchRawName) { CopyTo(&m_Data); (*m_pFunctor)(m_Data); return m_pDocumentHandler->endElement( pwchNamespaceUri, cchNamespaceUri, pwchLocalName, cchLocalName, pwchRawName, cchRawName); } virtual void CopyTo(void* dest) { ClassContentHandlers::iterator iter, iterEnd; iter=m_ChildHandlers.begin(); iterEnd = m_ChildHandlers.end(); for(;iter!= iterEnd; ++iter) (*iter)->CopyTo(dest); } };