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);
    }
};