//******************************* // XML OM test code // // ******************************* #include #include #include #include #include #include #include #include #include #include #include "mshtml.h" #include "msxml.h" #include "Utility.h" #include "EnumIDL.h" #include "ParseXML.h" // // Dump an element attribute member if present. // void DumpAttrib(IXMLElement *pElem, BSTR bstrAttribName) { VARIANT vProp; VariantInit(&vProp); if (SUCCEEDED(pElem->getAttribute(bstrAttribName, &vProp))) { if (vProp.vt == VT_BSTR) { printf(" %S=\"%S\"", bstrAttribName, vProp.bstrVal); } VariantClear(&vProp); } } // // Helper routine to quickly find out if this is a named element // currently only used to improve the format of the output. // BOOL IsNamedElement(IXMLElement *pElem) { BSTR bstrName; if (SUCCEEDED(pElem->get_tagName(&bstrName))) { if (bstrName) { SysFreeString(bstrName); return TRUE; } } return FALSE; } void DumpElement ( LPITEMIDLIST pidl, CPidlMgr *pCPidlMgr, CEnumIDList *pCEnumIDList, IXMLElement * pElem, XMLTAG tag ) { BSTR bstrTagName = NULL; BSTR bstrContent = NULL; IXMLElementCollection * pChildren; BSTR bstrITEM = L"ITEM"; BSTR bstrNAME = L"NAME"; BSTR bstrTYPE = L"TYPE"; BSTR bstrFOLDER = L"Folder"; BSTR bstrICON = L"ICON"; BSTR bstrBASE_URL = L"BASE-URL"; // // Dump the NODE. // pElem->get_tagName(&bstrTagName); if (bstrTagName) { if (!_wcsicmp(bstrTagName, bstrITEM)) { if (tag == T_ITEM) { // Skip internal ITEMs SysFreeString(bstrTagName); return; } else if (tag == T_ROOT) { // We are at the root // Drill down and look for ITEMs tag = T_NONE; } else { // Drill down tag = T_ITEM; // Create new PIDL pidl = pCPidlMgr->Create(); if(pidl) pCEnumIDList->AddToEnumList(pidl); } } else if (!_wcsicmp(bstrTagName, bstrNAME)) // Drill down tag = T_NAME; else if (!_wcsicmp(bstrTagName, bstrTYPE)) // Drill down tag =T_TYPE; else if (!_wcsicmp(bstrTagName, bstrICON)) // Drill down tag = T_ICON; else if (!_wcsicmp(bstrTagName, bstrBASE_URL)) // Drill down tag = T_BASE_URL; else { // We are not interested SysFreeString(bstrTagName); return; } } else { // Build PIDL XMLELEM_TYPE xmlElemType; PIDLDATA pidldata; if (SUCCEEDED(pElem->get_type((long *)&xmlElemType))) { if (xmlElemType == XMLELEMTYPE_TEXT) { if (SUCCEEDED(pElem->get_text(&bstrContent))) { if (bstrContent) { if (tag == T_TYPE) { if ( !_wcsicmp(bstrContent, bstrFOLDER)) // Later check on SHCONTF_FOLDERS pidldata.fFolder = TRUE; else pidldata.fFolder = FALSE; pidl = pCPidlMgr->SetDataPidl(pidl, &pidldata, FOLDER); } else if (tag == T_NAME) { WideCharToLocal(pidldata.szName, bstrContent, MAX_NAME); pidl = pCPidlMgr->SetDataPidl(pidl, &pidldata, NAME); } else if (tag == T_ICON) { TCHAR szIcon[MAX_NAME]; WideCharToLocal(szIcon, bstrContent, MAX_NAME); int index = AddIconImageList(g_himlLarge, szIcon); AddIconImageList(g_himlSmall, szIcon); pidldata.iIcon = index; pidl = pCPidlMgr->SetDataPidl(pidl, &pidldata, ICON); } else if (tag == T_BASE_URL) { WideCharToLocal(pidldata.szUrl, bstrContent, MAX_NAME); pidl = pCPidlMgr->SetDataPidl(pidl, &pidldata, URL); } } SysFreeString(bstrContent); } } } return; // no need to free bstrTagName } // // Find the children if they exist. // if (SUCCEEDED(pElem->get_children(&pChildren)) && pChildren) { WALK_ELEMENT_COLLECTION(pChildren, pDisp) { // // pDisp will iterate over an IDispatch for each item in the collection. // IXMLElement * pChild; if (SUCCEEDED(pDisp->QueryInterface(IID_IXMLElement, (void **)&pChild))) { DumpElement(pidl, pCPidlMgr, pCEnumIDList, pChild, tag ); pChild->Release(); } } END_WALK_ELEMENT_COLLECTION(pDisp); pChildren->Release(); } if (bstrTagName) SysFreeString(bstrTagName); } int MyStrToOleStrN(LPOLESTR pwsz, int cchWideChar, LPCTSTR psz) { int i; i=MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, cchWideChar); if (!i) { //DBG_WARN("MyStrToOleStrN string too long; truncated"); pwsz[cchWideChar-1]=0; } else ZeroMemory(pwsz+i, sizeof(OLECHAR)*(cchWideChar-i)); return i; } HRESULT GetSourceXML(IXMLDocument **ppDoc, TCHAR *pszURL) { PSTR pszErr = NULL; IStream *pStm = NULL; IPersistStreamInit *pPSI = NULL; IXMLElement *pElem = NULL; WCHAR *pwszURL=NULL; BSTR pBURL=NULL; HRESULT hr; int cszURL = 0; // // Create an empty XML document. // hr = CoCreateInstance(CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDocument, (void**)ppDoc); CHECK_ERROR (*ppDoc, "CoCreateInstance Failed"); pwszURL = (WCHAR *)LocalAlloc(LMEM_FIXED, ((sizeof(WCHAR))*(strlen(pszURL) + 2))); CHECK_ERROR(pwszURL, "Mem Alloc Failure"); cszURL = MyStrToOleStrN(pwszURL, (strlen(pszURL) + 1), pszURL); CHECK_ERROR(cszURL, "Failed to convert to UNICODE"); pBURL = SysAllocString(pwszURL); CHECK_ERROR(pBURL, "Mem Alloc Failure"); LocalFree(pwszURL); hr = (*ppDoc)->put_URL(pBURL); if (! SUCCEEDED(hr)) { // // Failed to parse stream, output error information. // IXMLError *pXMLError = NULL ; XML_ERROR xmle; hr = (*ppDoc)->QueryInterface(IID_IXMLError, (void **)&pXMLError); CHECK_ERROR(SUCCEEDED(hr), "Couldn't get IXMLError"); // ASSERT(pXMLError); hr = pXMLError->GetErrorInfo(&xmle); SAFERELEASE(pXMLError); CHECK_ERROR(SUCCEEDED(hr), "GetErrorInfo Failed"); SysFreeString(xmle._pszFound); SysFreeString(xmle._pszExpected); SysFreeString(xmle._pchBuf); } done: // Clean up. // // Release any used interfaces. // SAFERELEASE(pPSI); SAFERELEASE(pStm); // SAFERELEASE(*ppDoc); Do it in the caller!!!!!!!!!!!!!!!!!! SysFreeString(pBURL); return hr; }