XMLIterator.h
上传用户:kj0090
上传日期:2007-03-02
资源大小:39k
文件大小:5k
源码类别:

xml/soap/webservice

开发平台:

C/C++

  1. /***********************************************************************
  2. *
  3. * This module is part of the XMLGUI system 
  4. *
  5. * File name:       XMLIterator.h
  6. *
  7. * Creation date:   [15 AUGUST 2002] 
  8. *
  9. * Author(s):       [Kolosenko Ruslan]
  10. *
  11. * Description:     Declares the template class CXMLIteratable
  12. *
  13. **********************************************************************/
  14. #ifndef AFX_XML_ITERATOR_H_RKOL_8_15_2002_
  15. #define AFX_XML_ITERATOR_H_RKOL_8_15_2002_
  16. #if _MSC_VER > 1000
  17. #pragma once
  18. #endif // _MSC_VER > 1000
  19. #include "XMLTags.h"
  20. template <class TagType> class CXMLIteratable
  21. {
  22. public:
  23.        // constructor, accepts pointer to the enclosing tag element
  24.     CXMLIteratable(IXMLElement* pEnclosingTag)
  25.     {
  26.         HRESULT hr;
  27.            // set initial values for data members
  28.         m_pCollection    = NULL;
  29.         m_pCurrent       = NULL;
  30.         m_nCurrIndex     = 0;
  31.         m_nChildrenCount = 0;
  32.            // get reference to IXMLElement interface of the enclosing tag
  33.         hr = pEnclosingTag->QueryInterface(IID_IXMLElement,(void**)&m_pEnclosing);
  34.         WATCH_XML_EXCEPTION(hr);
  35.            // get and store reference to the XMLElementCollection interface
  36.            // and number of child nodes of the enclosing tag
  37.         hr = m_pEnclosing->get_children(&m_pCollection);
  38.         if ( SUCCEEDED(hr) && m_pCollection )
  39.         {
  40.             hr = m_pCollection->get_length(&m_nChildrenCount);
  41.             WATCH_XML_EXCEPTION(hr)
  42.         }        
  43.     }
  44.     virtual ~CXMLIteratable()
  45.     {
  46.            // free all used COM interfaces
  47.         if ( m_pCurrent )    m_pCurrent->Release();
  48.         if ( m_pCollection ) m_pCollection->Release();
  49.         if ( m_pEnclosing )  m_pEnclosing->Release();
  50.     }
  51.        // dereference operator, returns TagType object corresponding
  52.        // to the current XMLElement
  53.     TagType operator*()
  54.     {
  55.         if ( !m_pCurrent )
  56.         {
  57.             throw CXMLParsingException(_T("Dereferencing a non-positioned iterator"));
  58.         }
  59.         return TagType(m_pCurrent);
  60.     }
  61.     
  62.        // start iterating, moves cursor to the beginning of the nodes collection
  63.     void Begin()
  64.     {
  65.            // release previously used COM interface pointers if any
  66.         if ( m_pCurrent ) m_pCurrent->Release();
  67.         m_pCurrent = NULL;
  68.                 
  69.            // try to find first child node that can be converted to TagType
  70.            // start from the beginning of the collection
  71.         m_nCurrIndex = 0;
  72.         FindNext();
  73.     }
  74.     
  75.        // determines whether the end of the iterating loop was reached
  76.     BOOL AtEnd()
  77.     {
  78.            // if no next element was previously found - we finished iterating
  79.         return m_pCurrent ? FALSE : TRUE;
  80.     }
  81.        // prefix increment
  82.        // moves the cursor to the next child element of type TagType
  83.        // returns the modified iterator object
  84.     CXMLIteratable& operator++()
  85.     {
  86.         if ( AtEnd() )
  87.         {      // cannot move over the end of the list
  88.             throw CXMLParsingException(_T("Moving iterator out of range"));
  89.         }
  90.         m_nCurrIndex++;
  91.         FindNext();    // try to find the next acceptable element
  92.         return *this;  // return the object with the cursor moved
  93.     }
  94. protected:
  95.        // help function for retrieving next element while iterating
  96.     void FindNext()
  97.     {
  98.         HRESULT hr;
  99.            // release current element pointer
  100.         if ( m_pCurrent ) m_pCurrent->Release();
  101.         m_pCurrent = NULL;
  102.         VARIANT var1; // variants for retrieving control's IXMLElement pointer
  103.         VARIANT var2; // needed for the call to pChildren->item() only
  104.         var1.vt = VT_UINT;
  105.         var2.vt = VT_EMPTY;
  106.            // and now try to find the next child node matching TagType
  107.         while ( m_nCurrIndex < m_nChildrenCount )
  108.         {
  109.             var1.uintVal = m_nCurrIndex;
  110.             hr = m_pCollection->item(var1,var2,(IDispatch**)&m_pCurrent);
  111.             if ( SUCCEEDED(hr) && TagType::IsTypeValid(m_pCurrent) )
  112.             {
  113.                 break;   // next element of type TagType found
  114.             }
  115.                // element does not match or COM failure - release obtained pointer
  116.             if ( m_pCurrent ) m_pCurrent->Release();
  117.             m_pCurrent = NULL;
  118.             if ( FAILED(hr) ) break;  // break the loop in the case of COM failure
  119.             m_nCurrIndex++;  // and check the next element if just TagType mismatch
  120.         }
  121.     }
  122.        // data members
  123.     long                      m_nCurrIndex;      // current position in the collection
  124.     long                      m_nChildrenCount;  // total number of child elements
  125.     IXMLElementCollection*    m_pCollection;     // COM pointer to the collection
  126.     IXMLElement*              m_pEnclosing;      // COM pointer to the enclosing element
  127.     IXMLElement*              m_pCurrent;        // pointer to the current element (cursor)
  128. };
  129.    // instantiations of CXMLIteratable for some commonly used tag types
  130. typedef CXMLIteratable<CXMLTag>            CXMLIterator;
  131. typedef CXMLIteratable<CXMLDialogTag>      CXMLDialogIterator;
  132. typedef CXMLIteratable<CXMLControlTag>     CXMLControlIterator;
  133. #endif // AFX_XML_ITERATOR_H_RKOL_8_15_2002_