1 // XMLElementCollection.cpp : Implementation of CXMLElementCollection
3 //#include "Activexml.h"
4 #include "XMLElementCollection.h"
6 CXMLElementCollection::CXMLElementCollection()
11 CXMLElementCollection::~CXMLElementCollection()
16 HRESULT
CXMLElementCollection::Add(IXMLElement
*pElement
)
23 m_cElements
.push_back( CComQIPtr
<IXMLElement
, &IID_IXMLElement
>(pElement
));
28 /////////////////////////////////////////////////////////////////////////////
29 // CXMLElementCollection
31 HRESULT STDMETHODCALLTYPE
CXMLElementCollection::put_length(/* [in] */ long v
)
33 // Why does MS define a method that has no purpose?
38 HRESULT STDMETHODCALLTYPE
CXMLElementCollection::get_length(/* [out][retval] */ long __RPC_FAR
*p
)
44 *p
= m_cElements
.size();
49 HRESULT STDMETHODCALLTYPE
CXMLElementCollection::get__newEnum(/* [out][retval] */ IUnknown __RPC_FAR
*__RPC_FAR
*ppUnk
)
55 // Perhaps the most overly complicated method ever...
56 HRESULT STDMETHODCALLTYPE
CXMLElementCollection::item(/* [in][optional] */ VARIANT var1
, /* [in][optional] */ VARIANT var2
, /* [out][retval] */ IDispatch __RPC_FAR
*__RPC_FAR
*ppDisp
)
67 // If var1 is a number, the caller wants the element at the specified index
69 if (vIndex
.ChangeType(VT_I4
, &var1
) == S_OK
)
71 long nIndex
= vIndex
.intVal
;
72 if (nIndex
< 0 || nIndex
>= m_cElements
.size())
76 // Get the element at the specified index
77 m_cElements
[nIndex
]->QueryInterface(IID_IDispatch
, (void **) ppDisp
);
81 // If var1 is a string, the caller wants a collection of all elements with
82 // the matching tagname, unless var2 contains an index or if there is only
83 // one in which case just the element is returned.
86 if (FAILED(vName
.ChangeType(VT_BSTR
, &var1
)))
91 // Compile a list of elements matching the name
92 ElementList cElements
;
93 ElementList::iterator i
;
95 for (i
= m_cElements
.begin(); i
!= m_cElements
.end(); i
++)
97 CComQIPtr
<IXMLElement
, &IID_IXMLElement
> spElement
;
98 BSTR bstrTagName
= NULL
;
99 (*i
)->get_tagName(&bstrTagName
);
102 if (wcscmp(bstrTagName
, vName
.bstrVal
) == 0)
104 cElements
.push_back(*i
);
106 SysFreeString(bstrTagName
);
110 // Are there any matching elements?
111 if (cElements
.empty())
116 // Does var2 contain an index?
117 if (var2
.vt
== VT_I4
)
119 long nIndex
= var2
.vt
;
120 if (nIndex
< 0 || nIndex
>= cElements
.size())
125 // Get the element at the specified index
126 cElements
[nIndex
]->QueryInterface(IID_IDispatch
, (void **) ppDisp
);
130 // Is there more than one element?
131 if (cElements
.size() > 1)
133 // Create another collection
134 CXMLElementCollectionInstance
*pCollection
= NULL
;
135 CXMLElementCollectionInstance::CreateInstance(&pCollection
);
136 if (pCollection
== NULL
)
138 return E_OUTOFMEMORY
;
141 if (FAILED(pCollection
->QueryInterface(IID_IDispatch
, (void **) ppDisp
)))
143 pCollection
->Release();
147 // Add elements to the collection
148 for (i
= cElements
.begin(); i
!= cElements
.end(); i
++)
150 pCollection
->Add(*i
);
156 // Return the pointer to the element
157 if (FAILED(cElements
[0]->QueryInterface(IID_IDispatch
, (void **) ppDisp
)))