/* * (c) Copyright Ascensio System SIA 2010-2014 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) * version 3 as published by the Free Software Foundation. In accordance with * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect * that Ascensio System SIA expressly excludes the warranty of non-infringement * of any third-party rights. * * This program is distributed WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html * * You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, * EU, LV-1021. * * The interactive user interfaces in modified source and object code versions * of the Program must display Appropriate Legal Notices, as required under * Section 5 of the GNU AGPL version 3. * * Pursuant to Section 7(b) of the License you must retain the original Product * logo when distributing the program. Pursuant to Section 7(e) we decline to * grant you any rights under trademark law for use of our trademarks. * * All the Product's GUI elements, including illustrations and icon sets, as * well as technical writing content are licensed under the terms of the * Creative Commons Attribution-ShareAlike 4.0 International. See the License * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ #pragma once #import rename_namespace("XML") #include #include namespace MSXML { struct __declspec(uuid("f6d90f11-9c73-11d3-b32e-00c04f990bb4")) DOMDocument; struct __declspec(uuid("f5078f1b-c551-11d3-89b9-0000f81fe221")) DOMDocument26; struct __declspec(uuid("f5078f32-c551-11d3-89b9-0000f81fe221")) DOMDocument30; struct __declspec(uuid("88d969c0-f192-11d4-a65f-0040963251e5")) DOMDocument40; struct __declspec(uuid("88d969e5-f192-11d4-a65f-0040963251e5")) DOMDocument50; struct __declspec(uuid("88d96a05-f192-11d4-a65f-0040963251e5")) DOMDocument60; } #define MSXMLDocument __uuidof(MSXML2::DOMDocument60) namespace XmlUtils { static CString strInvalidValue = _T("x(-Jdl%^8sFGs@gkp14jJU(90dyjhjnb*EcfFf%#2124sf98hc"); static _bstr_t g_cpszXML_TextExt = L"./text()"; static int GetDigit(TCHAR c) { if (c >= '0' && c <= '9') return (int)(c - '0'); if (c >= 'a' && c <= 'f') return 10 + (int)(c - 'a'); if (c >= 'A' && c <= 'F') return 10 + (int)(c - 'A'); return 0; } static int GetColor(const CString& string) { int blue = 0; int green = 0; int red = 0; CString color = string; color = color.Trim(); if (color.Find(_T("0x"))!=-1) color.Delete(0,2); if (color.Find(_T("#"))!=-1) color.Delete(0,1); while (color.GetLength() < 6) color = _T("0") + color; red = 16*GetDigit(color[0]) + GetDigit(color[1]); green = 16*GetDigit(color[2]) + GetDigit(color[3]); blue = 16*GetDigit(color[4]) + GetDigit(color[5]); return RGB(red, green, blue); } static BOOL GetBoolean(const CString& string) { CString s = string; s.MakeLower(); return (s == _T("true")); } inline static int GetInteger(const CString& string) { return _ttoi(string); } inline static double GetDouble(const CString& string) { double d = 0; _stscanf(string, _T(" %lf"), &d); return d; } inline static float GetFloat(const CString& string) { float f = 0; _stscanf(string, _T(" %f"), &f); return f; } inline static int GetInteger(BSTR string) { return _wtoi(string); } inline static double GetDouble(BSTR string) { double d = 0; swscanf(string, L" %lf", &d); return d; } inline static float GetFloat(BSTR string) { float f = 0; swscanf(string, L" %f", &f); return f; } static CString GetLower(const CString& string) { CString s = string; s.MakeLower(); return s; } static CString GetNodeAttrib(XML::IXMLDOMNodePtr node, const CString& attrib, const CString& def = _T("")) { try { if (node == NULL || attrib.GetLength() < 1) return def; _bstr_t x = attrib; IXMLDOMNamedNodeMapPtr attributes = node->attributes; if (attributes == NULL) return def; IXMLDOMNodePtr tempNode; attributes->getNamedItem(x, &tempNode); if(tempNode == NULL) return def; BSTR str; tempNode->get_text(&str); CString s = CString(str); SysFreeString(str); return s; } catch (...) { } return def; } static CString GetNodeAttribExt(XML::IXMLDOMNodePtr node, const CString& attrib, const CString& def = _T("")) { try { if (node == NULL || attrib.GetLength() < 1) return def; _bstr_t x = attrib; if (node->attributes == NULL || node->attributes->getNamedItem(x) == NULL) return def; VARIANT var; node->attributes->getNamedItem(x)->get_nodeValue(&var); if (VT_BSTR == var.vt) { CString s = (CString)var.bstrVal; VariantClear(&var); return s; } VariantClear(&var); } catch (...) { } return def; } static CString GetNodeText(XML::IXMLDOMNodePtr node, const CString& def = _T("")) { try { if (node == NULL) return def; CString s; s = node->text.GetBSTR(); return s; } catch (...) { } return def; } static CString GetNodeXml(XML::IXMLDOMNodePtr node, const CString& subnode, const CString& def = _T("")) { try { if (node == NULL) return def; CString s; if (subnode.GetLength() < 1) s = node->xml.GetBSTR(); else { _bstr_t x = subnode; s = node->selectSingleNode(x)->xml.GetBSTR(); } return s; } catch (...) { } return def; } static CString GetNodeValue(XML::IXMLDOMNodePtr node, const CString& subnode, const CString& def = _T("")) { try { if (node == NULL || subnode.GetLength() < 1) return def; _bstr_t x = subnode; if (node->selectSingleNode(x) == NULL) return def; CString s; s = node->selectSingleNode(x)->text.GetBSTR(); return s; } catch (...) { } return def; } static CString GetNodeValueExt(XML::IXMLDOMNodePtr ptrNode, const CString& sDef = _T("")) { try { if (ptrNode == NULL) return sDef; CString sPath = _T("./text()"); XML::IXMLDOMNodeList* pChildTextNodeList = NULL; BSTR bsPath = sPath.AllocSysString(); ptrNode->raw_selectNodes(bsPath, &pChildTextNodeList); SysFreeString(bsPath); if (NULL!=pChildTextNodeList) { CString sRet; long lCount = 0; pChildTextNodeList->get_length(&lCount); for (long lIndex = 0; lIndex < lCount; lIndex++) { XML::IXMLDOMNode *pChildTextNode = NULL; pChildTextNodeList->get_item(lIndex, &pChildTextNode); if (NULL==pChildTextNode) continue; VARIANT vt; pChildTextNode->get_nodeValue(&vt); pChildTextNode->Release(); CString sValue; if (VT_BSTR == vt.vt) sValue = vt.bstrVal; VariantClear(&vt); sRet += sValue; } pChildTextNodeList->Release(); return sRet; } } catch (...) { } return sDef; } static BOOL GetNodeTextTyped(XML::IXMLDOMNodePtr node, _variant_t* variant, const CString& type = _T("bin.base64")) { try { if (node == NULL) return FALSE; BSTR bstrType = type.AllocSysString(); node->put_dataType(bstrType); SysFreeString(bstrType); *variant = node->nodeTypedValue; return TRUE; } catch (...) { } return FALSE; } static CString GetNodeAttrib(XML::IXMLDOMNodeListPtr nodes, int index, const CString& attrib, const CString& def = _T("")) { try { if (nodes == NULL || index < 0 || index >= nodes->length) return def; CString s = GetNodeAttrib(nodes->item[index], attrib, def); return s; } catch (...) { } return def; } static CString GetNodeText(XML::IXMLDOMNodeListPtr nodes, int index, const CString& def = _T("")) { try { if (nodes == NULL || index < 0 || index >= nodes->length) return def; CString s = GetNodeText(nodes->item[index], def); return s; } catch (...) { } return def; } static CString GetNodeXml(XML::IXMLDOMNodeListPtr nodes, int index, const CString& def = _T("")) { try { if (nodes == NULL || index < 0 || index >= nodes->length) return def; CString s = GetNodeXml(nodes->item[index], def); return s; } catch (...) { } return def; } static CString GetNodeValue(XML::IXMLDOMNodeListPtr nodes, int index, const CString& subnode, const CString& def = _T("")) { try { if (nodes == NULL || index < 0 || index >= nodes->length) return def; CString s = GetNodeValue(nodes->item[index], subnode, def); return s; } catch (...) { } return def; } static BOOL GetNodeTextTyped(XML::IXMLDOMNodeListPtr nodes, int index, _variant_t* variant, const CString& type = _T("bin.base64")) { try { if (nodes == NULL || index < 0 || index >= nodes->length) return FALSE; return GetNodeTextTyped(nodes->item[index], variant, type); } catch (...) { } return FALSE; } class CXmlWriter { CString m_str; public: CXmlWriter() { m_str.Empty(); } CString GetXmlString() { return m_str; } void SetXmlString(const CString& strValue) { m_str = strValue; } BOOL SaveToFile(const CString& strFilePath, BOOL bEncodingToUTF8 = FALSE) { FILE* pFile = _tfopen(strFilePath, _T("wt")); if (!pFile) return FALSE; CStringA str; str = m_str; if (bEncodingToUTF8) #ifdef _UNICODE str = EncodingUnicodeToUTF8(); #else str = EncodingASCIIToUTF8(); #endif fprintf(pFile, str); fclose(pFile); return TRUE; } #ifdef _UNICODE CStringA EncodingUnicodeToUTF8() { int nLength = m_str.GetLength(); CStringA saStr; WideCharToMultiByte(CP_UTF8, 0, m_str.GetBuffer(), nLength + 1, saStr.GetBuffer(nLength*3 + 1), nLength*3, NULL, NULL); saStr.ReleaseBuffer(); return saStr; } #else CString EncodingASCIIToUTF8() { int nLength = m_str.GetLength(); wchar_t* pWStr = new wchar_t[nLength + 1]; if (!pWStr) return _T(""); pWStr[nLength] = 0; MultiByteToWideChar(CP_ACP, 0, m_str, nLength, pWStr, nLength); int nLengthW = (int) wcslen(pWStr); CString cStr; WideCharToMultiByte(CP_UTF8, 0, pWStr, nLengthW + 1, cStr.GetBuffer(nLengthW*3 + 1), nLengthW*3, NULL, NULL); cStr.ReleaseBuffer(); delete[] pWStr; return cStr; } #endif void WriteString(const CString& strValue) { m_str += strValue; } void WriteInteger(int Value, int Base = 10) { char str[33]; _itoa(Value, str, Base); m_str += str; } void WriteDouble(double Value) { CString str; str.Format(_T("%lf"), Value); m_str += str; } void WriteBoolean(BOOL Value) { if (Value) m_str += _T("true"); else m_str += _T("false"); } void WriteNodeBegin(const CString& strNodeName, BOOL bAttributed = FALSE) { m_str += _T("<") + strNodeName; if (!bAttributed) m_str += _T(">"); } void WriteNodeEnd(const CString& strNodeName, BOOL bEmptyNode = FALSE, BOOL bEndNode = TRUE) { if (bEmptyNode) { if (bEndNode) m_str += _T(" />"); else m_str += _T(">"); } else m_str += _T(""); } void WriteNode(const CString& strNodeName, const CString& strNodeValue) { if (strNodeValue.GetLength() == 0) m_str += _T("<") + strNodeName + _T("/>"); else m_str += _T("<") + strNodeName + _T(">") + strNodeValue + _T(""); } void WriteNode(const CString& strNodeName, int nValue, int nBase = 10, const CString& strTextBeforeValue = _T(""), const CString& strTextAfterValue = _T("")) { WriteNodeBegin(strNodeName); WriteString(strTextBeforeValue); WriteInteger(nValue, nBase); WriteString(strTextAfterValue); WriteNodeEnd(strNodeName); } void WriteNode(const CString& strNodeName, double dValue) { WriteNodeBegin(strNodeName); WriteDouble(dValue); WriteNodeEnd(strNodeName); } void WriteAttribute(const CString& strAttributeName, const CString& strAttributeValue) { m_str += _T(" ") + strAttributeName + _T("=\"") + strAttributeValue + _T("\""); } void WriteAttribute(const CString& strAttributeName, int nValue, int nBase = 10, const CString& strTextBeforeValue = _T(""), const CString& strTextAfterValue = _T("")) { WriteString(_T(" ") + strAttributeName + _T("=")); WriteString(_T("\"")); WriteString(strTextBeforeValue); WriteInteger(nValue, nBase); WriteString(strTextAfterValue); WriteString(_T("\"")); } void WriteAttribute(const CString& strAttributeName, double dValue) { WriteString(_T(" ") + strAttributeName + _T("=")); WriteString(_T("\"")); WriteDouble(dValue); WriteString(_T("\"")); } public: static void ReplaceSpecialCharacters (CString &sString) { sString.Replace (_T("&"), _T("&")); sString.Replace (_T("<"), _T("<")); sString.Replace (_T(">"), _T(">")); sString.Replace (_T("\""), _T(""")); sString.Replace (_T("'"), _T("'")); } }; class CXmlReader { CString m_str; XML::IXMLDOMDocument2Ptr m_pXmlDocument; XML::IXMLDOMNodeListPtr m_pXmlNodeList; protected: XML::IXMLDOMNodePtr m_pXmlNode; public: CXmlReader() { Clear(); m_pXmlDocument = NULL; if (FAILED(m_pXmlDocument.CreateInstance(__uuidof(MSXML::DOMDocument60)))) { if (FAILED(m_pXmlDocument.CreateInstance(__uuidof(MSXML::DOMDocument)))) { m_pXmlDocument = NULL; } } if (NULL != m_pXmlDocument) { m_pXmlDocument->setProperty( _bstr_t(_T("SelectionLanguage")), _variant_t(_T("XPath")) ); } } CXmlReader(BOOL bCreateDocument) { Clear(); m_pXmlDocument = NULL; if (bCreateDocument) { if (FAILED(m_pXmlDocument.CreateInstance(__uuidof(MSXML::DOMDocument60)))) { if (FAILED(m_pXmlDocument.CreateInstance(__uuidof(MSXML::DOMDocument)))) { m_pXmlDocument = NULL; } } if (NULL != m_pXmlDocument) { m_pXmlDocument->setProperty( _bstr_t(_T("SelectionLanguage")), _variant_t(_T("XPath")) ); } } } void Clear() { m_str.Empty(); m_pXmlNode = NULL; m_pXmlNodeList = NULL; } CString GetXmlString() { return m_str; } BOOL SetXmlString(const CString& strValue) { if (NULL == m_pXmlDocument) return FALSE; try { _bstr_t bstrXml; bstrXml = strValue; if (_T("") != strValue && VARIANT_TRUE == m_pXmlDocument->loadXML(bstrXml)) { if (ReadRootNode()) { m_str = strValue; return TRUE; } } } catch (...) { } Clear(); return FALSE; } BOOL OpenFromXmlString(const CString& strXml) { return SetXmlString(strXml); } BOOL OpenFromXmlNode(XML::IXMLDOMNodePtr& pXmlNode) { m_pXmlNode = pXmlNode; if (pXmlNode == NULL) return FALSE; return TRUE; } BOOL OpenFromFile(const CString& strFilePath) { if (NULL == m_pXmlDocument) return FALSE; BSTR bstrFilePath = strFilePath.AllocSysString(); BOOL bSuccess = FALSE; try { if (VARIANT_TRUE == m_pXmlDocument->load(bstrFilePath)) bSuccess = ReadRootNode(); } catch (...) { } if (!bSuccess) Clear(); SysFreeString(bstrFilePath); return bSuccess; } CString ReadNodeName() { if (NULL == m_pXmlNode) return _T(""); CString sName; try { BSTR bsName; m_pXmlNode->get_nodeName(&bsName); sName = bsName; SysFreeString(bsName); } catch (...) { } return sName; } BOOL ReadRootNode() { if (NULL == m_pXmlDocument) return FALSE; try { m_pXmlNode = m_pXmlDocument->firstChild; return TRUE; } catch (...) { } m_pXmlNode = NULL; m_pXmlNodeList = NULL; return FALSE; } BOOL ReadRootNode(const CString& strRootNodeName) { if (_T("") == strRootNodeName) return ReadRootNode(); if (NULL == m_pXmlDocument) return FALSE; try { _bstr_t bstrNode; bstrNode = strRootNodeName; m_pXmlNode = m_pXmlDocument->selectSingleNode(bstrNode); return TRUE; } catch (...) { } m_pXmlNode = NULL; m_pXmlNodeList = NULL; return FALSE; } BOOL ReadNode(const CString& strSubNodeName) { if (NULL == m_pXmlNode) return FALSE; try { _bstr_t bstrNode; bstrNode = strSubNodeName; XML::IXMLDOMElementPtr pNewNode = m_pXmlNode->selectSingleNode(bstrNode); if (NULL != pNewNode) { m_pXmlNode = pNewNode; return TRUE; } } catch (...) { } m_pXmlNode = NULL; return FALSE; } BOOL ReadNodeList(const CString& strSubNodesName) { if (NULL == m_pXmlNode) return FALSE; try { _bstr_t bstrNodes; bstrNodes = strSubNodesName; XML::IXMLDOMNodeListPtr pNewNodeList = m_pXmlNode->selectNodes(bstrNodes); if (NULL != pNewNodeList) { m_pXmlNodeList = pNewNodeList; return TRUE; } } catch (...) { } m_pXmlNodeList = NULL; return FALSE; } CString ReadNodeAttributeOrValue(const CString& strSubNodeName, const CString& def = _T("")) { CString strAttributeValue = ReadNodeAttribute(strSubNodeName, strInvalidValue); if (strAttributeValue != strInvalidValue) return strAttributeValue; CString strNodeValue = ReadNodeValue(strSubNodeName, strInvalidValue); if (strNodeValue != strInvalidValue) return strNodeValue; return def; } CString ReadNodeValue(const CString& strSubNodeName, const CString& def = _T("")) { if (NULL == m_pXmlNode) return def; return GetNodeValue(m_pXmlNode, strSubNodeName, def); } CString ReadNodeAttribute(const CString& strAttributeName, const CString& def = _T("")) { if (NULL == m_pXmlNode) return def; return GetNodeAttrib(m_pXmlNode, strAttributeName, def); } CString ReadNodeText(const CString& def = _T("")) { if (NULL == m_pXmlNode) return def; return GetNodeText(m_pXmlNode, def); } CString ReadNodeXml(const CString& def = _T("")) { if (NULL == m_pXmlNode) return def; return GetNodeXml(m_pXmlNode, def); } BOOL ReadNodeTextTyped(_variant_t* variant, const CString& type = _T("bin.base64")) { if (NULL == m_pXmlNode) return FALSE; return GetNodeTextTyped(m_pXmlNode, variant, type); } CString ReadNodeName(int nIndex) { if (NULL == m_pXmlNodeList) return _T(""); CString sName; try { BSTR bsName; m_pXmlNodeList->item[nIndex]->get_nodeName(&bsName); sName = bsName; SysFreeString(bsName); } catch (...) { } return sName; } CString ReadNodeAttributeOrValue(int nIndex, const CString& strSubNodeName, const CString& def = _T("")) { CString strAttributeValue = ReadNodeAttribute(nIndex, strSubNodeName, strInvalidValue); if (strAttributeValue != strInvalidValue) return strAttributeValue; CString strNodeValue = ReadNodeValue(nIndex, strSubNodeName, strInvalidValue); if (strNodeValue != strInvalidValue) return strNodeValue; return def; } CString ReadNodeValue(int nIndex, const CString& strSubNodeName, const CString& def = _T("")) { if (NULL == m_pXmlNodeList) return def; return GetNodeValue(m_pXmlNodeList, nIndex, strSubNodeName, def); } CString ReadNodeAttribute(int nIndex, const CString& strAttributeName, const CString& def = _T("")) { if (NULL == m_pXmlNodeList) return def; return GetNodeAttrib(m_pXmlNodeList, nIndex, strAttributeName, def); } CString ReadNodeText(int nIndex, const CString& def = _T("")) { if (NULL == m_pXmlNodeList) return def; return GetNodeText(m_pXmlNodeList, nIndex, def); } CString ReadNodeXml(int nIndex, const CString& def = _T("")) { if (NULL == m_pXmlNodeList) return def; return GetNodeXml(m_pXmlNodeList, nIndex, def); } BOOL ReadNodeTextTyped(int nIndex, _variant_t* variant, const CString& type = _T("bin.base64")) { if (NULL == m_pXmlNodeList) return FALSE; return GetNodeTextTyped(m_pXmlNodeList, nIndex, variant, type); } int GetLengthList() { try { if (NULL == m_pXmlNodeList) return 0; int length = m_pXmlNodeList->length; return length; } catch (...) { } return 0; } BOOL GetNode(XML::IXMLDOMNodePtr& pXmlNode) { pXmlNode = m_pXmlNode; return (m_pXmlNode != NULL); } BOOL GetNode(int nIndex, XML::IXMLDOMNodePtr& pXmlNode) { if (m_pXmlNodeList == NULL) return FALSE; pXmlNode = m_pXmlNodeList->item[nIndex]; return TRUE; } }; }; namespace XmlUtils { static LPCTSTR g_cpszSADescriptorNodeName = _T("SADescriptor"); static LPCTSTR g_cpszSADimsAttributeName = _T("SADims"); static LPCTSTR g_cpszSASizeNodeNameFormat = _T("Size%d"); static LPCTSTR g_cpszSADataNodeName = _T("SAData"); static LPCTSTR g_cpszVariantTypeNodeAttr = _T("type"); struct SDispatchProperty { SDispatchProperty() : m_sName(_T("")) { } SDispatchProperty(const CString &sName, const VARIANT &var) : m_sName(sName) , m_varValue(var) { } CString m_sName; VARIANT m_varValue; }; class CDispatchPropertyList : public CAtlArray { public: CDispatchPropertyList() { } virtual ~CDispatchPropertyList() { size_t nCount = GetCount(); for (size_t nIndex = 0; nIndex < nCount; nIndex++) { if ((VT_BSTR==GetAt(nIndex).m_varValue.vt)&&(NULL!=GetAt(nIndex).m_varValue.bstrVal)) { SysFreeString(GetAt(nIndex).m_varValue.bstrVal); } else if ((0!=(VT_ARRAY & GetAt(nIndex).m_varValue.vt))&&(NULL!=GetAt(nIndex).m_varValue.parray)) SafeArrayDestroy(GetAt(nIndex).m_varValue.parray); } } }; static BOOL GetPropertyList(IDispatch *pDisp, CDispatchPropertyList &arProp, INVOKEKIND nType) { if (NULL==pDisp) return FALSE; ITypeInfo *pTypeInfo = NULL; pDisp->GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, &pTypeInfo); if (NULL==pTypeInfo) return FALSE; TYPEATTR* pTypeAttr = NULL; HRESULT hRes = pTypeInfo->GetTypeAttr(&pTypeAttr); if (S_OK!=hRes) { pTypeInfo->Release(); return FALSE; } int nMethodCount = pTypeAttr->cFuncs; for (int i=0; iGetFuncDesc(i, &pFuncDesc); if (S_OK!=hRes) continue; if (0!=pFuncDesc->cParams) continue; if (nType!=pFuncDesc->invkind) continue; BSTR bsName; unsigned int nCount; hRes = pTypeInfo->GetNames(pFuncDesc->memid, &bsName, 1, &nCount); if (S_OK!=hRes) continue; oPropRec.m_sName = bsName; SysFreeString(bsName); { DISPPARAMS dispParam; dispParam.cArgs = 0; dispParam.cNamedArgs = 0; dispParam.rgdispidNamedArgs = NULL; dispParam.rgvarg = NULL; hRes = pDisp->Invoke(pFuncDesc->memid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dispParam, &oPropRec.m_varValue, NULL, NULL); } pTypeInfo->ReleaseFuncDesc(pFuncDesc); arProp.Add(oPropRec); } pTypeInfo->ReleaseTypeAttr(pTypeAttr); pTypeInfo->Release(); return TRUE; } static BOOL ApplyPropertyList(IDispatch *pDisp, CDispatchPropertyList &arProp) { if (NULL==pDisp) return FALSE; long lCount = (long)arProp.GetCount(); for (long i=0; iGetIDsOfNames(IID_NULL, &szMember, 1, LOCALE_SYSTEM_DEFAULT, &dispid); DISPPARAMS dispParam; DISPID dispidNamed = DISPID_PROPERTYPUT; dispParam.cArgs = 1; dispParam.cNamedArgs = 1; dispParam.rgdispidNamedArgs = &dispidNamed; dispParam.rgvarg = &arProp[i].m_varValue; HRESULT hr = pDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &dispParam, NULL, NULL, NULL); } return TRUE; } class CDispatchXmlWriter : public CXmlWriter { public: CDispatchXmlWriter() { } ~CDispatchXmlWriter() { } void WriteNode(const CString& sName, const CLSID &clsid) { CStringW swGUID; int nSize = StringFromGUID2(clsid, swGUID.GetBuffer(50), 50); swGUID.ReleaseBuffer(nSize); CString sGUID; sGUID = swGUID; CXmlWriter::WriteNode(sName,sGUID); } void WriteNode(LPSAFEARRAY psa) { if (NULL==psa) return; UINT nDim = psa->cDims; if (0==nDim) return; ULONG ulSADataSize = 1; for (UINT nIndex = 0; nIndex < nDim; nIndex++) ulSADataSize *= psa->rgsabound[nIndex].cElements; if (0==ulSADataSize) return; CString sTemp; CXmlWriter::WriteNodeBegin(g_cpszSADescriptorNodeName, TRUE); CXmlWriter::WriteAttribute(g_cpszSADimsAttributeName, (int)nDim); CXmlWriter::WriteString(_T(">")); for (UINT nIndex = 0; nIndex < nDim; nIndex++) { sTemp.Format(g_cpszSASizeNodeNameFormat,nIndex); CXmlWriter::WriteNode(sTemp, (long)(psa->rgsabound[nIndex].cElements)); } CXmlWriter::WriteNodeEnd(g_cpszSADescriptorNodeName, FALSE); if (BinaryToBase64((LPBYTE)psa->pvData, ulSADataSize, sTemp)) CXmlWriter::WriteNode(g_cpszSADataNodeName, sTemp); else CXmlWriter::WriteNode(g_cpszSADataNodeName, _T("")); } void WriteNode(const CString &sName, const VARIANT &val) { if ((0!=(VT_VECTOR & val.vt)) || (0!=(VT_BYREF & val.vt))) return; if ((0!=(VT_ARRAY & val.vt))&&(VT_UI1 != (VT_TYPEMASK & val.vt))) return; CXmlWriter::WriteNodeBegin(sName, TRUE); CXmlWriter::WriteAttribute(g_cpszVariantTypeNodeAttr, val.vt); CXmlWriter::WriteString(_T(">")); if (0!=(VT_ARRAY & val.vt)) WriteNode(val.parray); else WriteString(VariantToString(val)); CXmlWriter::WriteNodeEnd(sName, FALSE); } void WritePropertyList(CDispatchPropertyList &arProp) { size_t nCount = arProp.GetCount(); for (size_t nIndex = 0; nIndexselectSingleNode(bstrNode); if (NULL==pNode) return 0; XML::IXMLDOMNodeListPtr pNodeList = pNode->selectNodes("*"); if (NULL != pNodeList) { long lNodeCount = pNodeList->length; CString sNodeName, sType, sValue; VARIANT val; for (long lIndex = 0; lIndexitem[lIndex]; sNodeName = ptrNode->baseName.GetBSTR(); sType = XmlUtils::GetNodeAttrib(ptrNode, g_cpszVariantTypeNodeAttr); sValue = ptrNode->text.GetBSTR(); val.vt = _ttoi(sType); if ((0!=(VT_VECTOR & val.vt)) || (0!=(VT_BYREF & val.vt))) continue; if (0!=(VT_ARRAY & val.vt)) { if (VT_UI1 != (VT_TYPEMASK & val.vt)) continue; if (!GetSafeArray(ptrNode, val.parray)) continue; } else { if (!GetVariantValue(sType, sValue, val)) continue; } arProp.Add(SDispatchProperty(sNodeName, val)); } } } catch (...) { } return (arProp.GetCount()); } protected: BOOL GetSafeArray(XML::IXMLDOMNodePtr ptrNode, LPSAFEARRAY &psa) { long lDims = 0; LPSAFEARRAYBOUND psabound = NULL; try { long lSize = 1; { _bstr_t bstrNode; bstrNode = g_cpszSADescriptorNodeName; XML::IXMLDOMElementPtr pDescriptionNode = ptrNode->selectSingleNode(bstrNode); CString sTemp = XmlUtils::GetNodeAttrib(pDescriptionNode, g_cpszSADimsAttributeName); lDims = _ttoi(sTemp); if (0==lDims) return FALSE; psabound = new SAFEARRAYBOUND[lDims]; if (NULL==psabound) return FALSE; for (long i=0; iselectSingleNode(bstrNode); CString sTemp; sTemp = pDataNode->text.GetBSTR(); if (!Base64ToBinary(sTemp, (LPBYTE)psa->pvData, lSize)) { delete []psabound; return FALSE; } } catch (...) { if (NULL != psabound) delete []psabound; return FALSE; } delete []psabound; return TRUE; } BOOL GetVariantValue(const CString &sType, const CString &sValue, VARIANT &val) { if ((sType.IsEmpty())||(sValue.IsEmpty())) return FALSE; val.vt = _ttoi(sType); BOOL bRet = TRUE; switch (VT_TYPEMASK & val.vt) { case VT_I2: val.iVal = _ttoi(sValue); break; case VT_I4: val.lVal = _ttoi(sValue); break; case VT_R4: val.fltVal = (float)_tstof(sValue); break; case VT_R8: val.dblVal = _tstof(sValue); break; case VT_DATE: val.date = _tstof(sValue); break; case VT_BSTR: val.bstrVal = sValue.AllocSysString(); break; case VT_BOOL: val.boolVal = (0!=_ttoi(sValue)) ? VARIANT_TRUE : VARIANT_FALSE; break; case VT_I1: val.cVal = _ttoi(sValue); break; case VT_UI1: val.bVal = _ttoi(sValue); break; case VT_UI2: val.uiVal = _ttoi(sValue); break; case VT_UI4: val.ulVal = _ttoi(sValue); break; case VT_I8: val.llVal = _ttoi(sValue); break; case VT_UI8: val.ullVal = _ttoi(sValue); break; case VT_INT: val.intVal = _ttoi(sValue); break; case VT_UINT: val.uintVal = _ttoi(sValue); break; case VT_DECIMAL: case VT_CY: case VT_EMPTY: case VT_NULL: case VT_SAFEARRAY: case VT_VOID: case VT_HRESULT: case VT_CARRAY: case VT_USERDEFINED: case VT_LPSTR: case VT_LPWSTR: case VT_RECORD: case VT_INT_PTR: case VT_UINT_PTR: case VT_FILETIME: case VT_BLOB: case VT_STREAM: case VT_STORAGE: case VT_STREAMED_OBJECT: case VT_STORED_OBJECT: case VT_BLOB_OBJECT: case VT_CF: case VT_CLSID: case VT_VERSIONED_STREAM: case VT_BSTR_BLOB: bRet = FALSE; break; } return bRet; } static BOOL Base64ToBinary(const CString& sData, BYTE* pData, int nSize) { if ((NULL==pData) || (0==nSize)) return FALSE; CStringA saData; saData = sData; return Base64Decode((LPCSTR)saData, saData.GetLength(), pData, &nSize); } }; }; namespace XmlUtils { class IXmlNode { public: virtual BOOL FromXmlNode(XML::IXMLDOMNodePtr& pXmlNode) = 0; virtual BOOL FromXmlString(const CString& strXml) = 0; virtual BOOL FromXmlFile(const CString& strXmlFilePath) = 0; }; class CXmlNodes { XML::IXMLDOMNodeListPtr m_pXmlNodes; public: CXmlNodes() { Clear(); } void Clear() { m_pXmlNodes = NULL; } BOOL IsValid() { return (NULL != m_pXmlNodes); } BOOL FromXmlNodes(XML::IXMLDOMNodeListPtr& pXmlNodes) { try { Clear(); m_pXmlNodes = pXmlNodes; } catch (...) { Clear(); } return IsValid(); } int GetCount() { if (!IsValid()) return 0; return m_pXmlNodes->length; } BOOL GetAt(int nIndex, IXmlNode& oXmlNode) { if (nIndex < 0) return FALSE; try { XML::IXMLDOMNodePtr pXmlNode = NULL; pXmlNode = m_pXmlNodes->item[nIndex]; return oXmlNode.FromXmlNode(pXmlNode); } catch (...) { } return FALSE; } }; class CXmlNode : public IXmlNode { XML::IXMLDOMDocument2Ptr m_pXmlDocument; XML::IXMLDOMNodePtr m_pXmlNode; IXMLDOMNamedNodeMapPtr m_pAttributes; private: void CreateDocument() { if (NULL == m_pXmlDocument) { if (FAILED(m_pXmlDocument.CreateInstance(__uuidof(MSXML::DOMDocument)))) { if (FAILED(m_pXmlDocument.CreateInstance(__uuidof(MSXML::DOMDocument)))) { m_pXmlDocument = NULL; } } } } void ReadRootNode() { m_pXmlNode = m_pXmlDocument->firstChild; } public: void ReadRootNode(const CString& strRootNodeName) { if (strRootNodeName.IsEmpty()) return ReadRootNode(); _bstr_t bstrNode; bstrNode = strRootNodeName; m_pXmlNode = m_pXmlDocument->selectSingleNode(bstrNode); } public: CXmlNode() { Clear(); } void Clear() { m_pXmlDocument = NULL; m_pXmlNode = NULL; m_pAttributes = NULL; } inline BOOL IsValid() { return (NULL != m_pXmlNode); } virtual BOOL FromXmlNode(XML::IXMLDOMNodePtr& pXmlNode) { try { Clear(); m_pXmlNode = pXmlNode; } catch (...) { Clear(); } return IsValid(); } virtual BOOL FromXmlString(const CString& strXml) { return FromXmlString(strXml, _T("")); } virtual BOOL FromXmlString(const CString& strXml, const CString& strNamespaces) { try { Clear(); CreateDocument(); if (_T("") != strNamespaces) { m_pXmlDocument->setProperty( _T("SelectionNamespaces"), _variant_t((LPCTSTR)strNamespaces)); } _bstr_t bstrXml; bstrXml = strXml; if (!strXml.IsEmpty() && VARIANT_TRUE == m_pXmlDocument->loadXML(bstrXml)) ReadRootNode(); } catch (...) { Clear(); } return IsValid(); } virtual BOOL FromXmlFile(const CString& strXmlFilePath) { BSTR bstrFilePath = strXmlFilePath.AllocSysString(); BOOL bSuccess = FALSE; try { Clear(); CreateDocument(); if (VARIANT_TRUE == m_pXmlDocument->load(bstrFilePath)) bSuccess = TRUE; ReadRootNode(); } catch (...) { bSuccess = FALSE; } SysFreeString(bstrFilePath); if (!bSuccess) Clear(); return IsValid(); } CString GetName() { if (!IsValid()) return _T(""); CString strName; try { BSTR bstrName; m_pXmlNode->get_nodeName(&bstrName); strName = bstrName; SysFreeString(bstrName); } catch (...) { } return strName; } BSTR ReadAttributeBase(const _bstr_t& bstrName) { if (!IsValid()) return NULL; if (NULL == m_pAttributes) { m_pAttributes = m_pXmlNode->attributes; if (NULL == m_pAttributes) return NULL; } IXMLDOMNodePtr tempNode; m_pAttributes->getNamedItem(bstrName, &tempNode); if (NULL == tempNode) return NULL; BSTR strRes; tempNode->get_text(&strRes); return strRes; } inline BSTR ReadAttribute(const CString& strAttibuteName) { _bstr_t bstrName = strAttibuteName; return ReadAttributeBase(bstrName); } BSTR ReadNodeTextBase(const _bstr_t& bsName) { if (!IsValid()) return NULL; try { XML::IXMLDOMNodePtr pNewNode = m_pXmlNode->selectSingleNode(bsName); if (NULL == pNewNode) return NULL; BSTR bsXml = NULL; pNewNode->get_text(&bsXml); return bsXml; } catch (...) { } return NULL; } inline BSTR ReadNodeText(const CString& strName) { _bstr_t bsName = strName; return ReadNodeTextBase(bsName); } inline int ReadAttributeIntBase(const _bstr_t& bstrName, const int& nDef = 0) { BSTR bsRes = ReadAttributeBase(bstrName); if (NULL == bsRes) return nDef; int nRes = XmlUtils::GetInteger(bsRes); SysFreeString(bsRes); return nRes; } inline int ReadAttributeInt(const CString& str, const int& nDef = 0) { _bstr_t bsName = str; return ReadAttributeIntBase(bsName, nDef); } inline int ReadValueIntBase(const _bstr_t& bstrName, const int& nDef = 0) { BSTR bsRes = ReadNodeTextBase(bstrName); if (NULL == bsRes) return nDef; int nRes = XmlUtils::GetInteger(bsRes); SysFreeString(bsRes); return nRes; } inline int ReadValueInt(const CString& str, const int& nDef = 0) { _bstr_t bsName = str; return ReadValueIntBase(bsName, nDef); } inline void UpdateAttributeBase(const _bstr_t& bstrName, int& nValue) { BSTR bsRes = ReadAttributeBase(bstrName); if (NULL == bsRes) return; nValue = XmlUtils::GetInteger(bsRes); SysFreeString(bsRes); } inline void UpdateAttributeBase(const _bstr_t& bstrName, long& nValue) { BSTR bsRes = ReadAttributeBase(bstrName); if (NULL == bsRes) return; nValue = (long)XmlUtils::GetInteger(bsRes); SysFreeString(bsRes); } inline void UpdateAttribute(const CString& strName, int& nValue) { _bstr_t bsName = strName; return UpdateAttributeBase(bsName, nValue); } inline void UpdateAttribute(const CString& strName, long& nValue) { _bstr_t bsName = strName; return UpdateAttributeBase(bsName, nValue); } inline void UpdateValueBase(const _bstr_t& bstrName, int& nValue) { BSTR bsRes = ReadNodeTextBase(bstrName); if (NULL == bsRes) return; nValue = XmlUtils::GetInteger(bsRes); SysFreeString(bsRes); } inline void UpdateValueBase(const _bstr_t& bstrName, long& nValue) { BSTR bsRes = ReadNodeTextBase(bstrName); if (NULL == bsRes) return; nValue = (long)XmlUtils::GetInteger(bsRes); SysFreeString(bsRes); } inline void UpdateValue(const CString& strName, int& nValue) { _bstr_t bsName = strName; return UpdateValueBase(bsName, nValue); } inline void UpdateValue(const CString& strName, long& nValue) { _bstr_t bsName = strName; return UpdateValueBase(bsName, nValue); } inline int ReadAttributeOrValueIntBase(const _bstr_t& bstrName, const int& nDef = 0) { BSTR bsRes = ReadAttributeBase(bstrName); if (NULL == bsRes) return ReadValueIntBase(bstrName, nDef); int nRes = XmlUtils::GetInteger(bsRes); SysFreeString(bsRes); return nRes; } inline int ReadAttributeOrValueInt(const CString& strName, const int& nDef = 0) { _bstr_t bsName = strName; return ReadAttributeOrValueIntBase(bsName, nDef); } inline void UpdateAttributeOrValueBase(const _bstr_t& bstrName, int& nValue) { BSTR bsRes = ReadAttributeBase(bstrName); if (NULL == bsRes) return UpdateValueBase(bstrName, nValue); nValue = XmlUtils::GetInteger(bsRes); SysFreeString(bsRes); } inline void UpdateAttributeOrValueBase(const _bstr_t& bstrName, long& nValue) { BSTR bsRes = ReadAttributeBase(bstrName); if (NULL == bsRes) return UpdateValueBase(bstrName, nValue); nValue = (long)XmlUtils::GetInteger(bsRes); SysFreeString(bsRes); } inline void UpdateAttributeOrValue(const CString& strName, int& nValue) { _bstr_t bsName = strName; return UpdateAttributeOrValueBase(bsName, nValue); } inline void UpdateAttributeOrValue(const CString& strName, long& nValue) { _bstr_t bsName = strName; return UpdateAttributeOrValueBase(bsName, nValue); } inline double ReadAttributeDoubleBase(const _bstr_t& bstrName, const double& nDef = 0) { BSTR bsRes = ReadAttributeBase(bstrName); if (NULL == bsRes) return nDef; double nRes = XmlUtils::GetDouble(bsRes); SysFreeString(bsRes); return nRes; } inline double ReadAttributeDouble(const CString& str, const double& nDef = 0) { _bstr_t bsName = str; return ReadAttributeDoubleBase(bsName, nDef); } inline double ReadValueDoubleBase(const _bstr_t& bstrName, const double& nDef = 0) { BSTR bsRes = ReadNodeTextBase(bstrName); if (NULL == bsRes) return nDef; double nRes = XmlUtils::GetDouble(bsRes); SysFreeString(bsRes); return nRes; } inline double ReadValueDouble(const CString& str, const double& nDef = 0) { _bstr_t bsName = str; return ReadValueDoubleBase(bsName, nDef); } inline void UpdateAttributeBase(const _bstr_t& bstrName, double& nValue) { BSTR bsRes = ReadAttributeBase(bstrName); if (NULL == bsRes) return; nValue = XmlUtils::GetDouble(bsRes); SysFreeString(bsRes); } inline void UpdateAttribute(const CString& strName, double& nValue) { _bstr_t bsName = strName; return UpdateAttributeBase(bsName, nValue); } inline void UpdateValueBase(const _bstr_t& bstrName, double& nValue) { BSTR bsRes = ReadNodeTextBase(bstrName); if (NULL == bsRes) return; nValue = XmlUtils::GetDouble(bsRes); SysFreeString(bsRes); } inline void UpdateValue(const CString& strName, double& nValue) { _bstr_t bsName = strName; return UpdateValueBase(bsName, nValue); } inline double ReadAttributeOrValueDoubleBase(const _bstr_t& bstrName, const double& nDef = 0) { BSTR bsRes = ReadAttributeBase(bstrName); if (NULL == bsRes) return ReadValueDoubleBase(bstrName, nDef); double nRes = XmlUtils::GetDouble(bsRes); SysFreeString(bsRes); return nRes; } inline double ReadAttributeOrValueDouble(const CString& strName, const double& nDef = 0) { _bstr_t bsName = strName; return ReadAttributeOrValueDoubleBase(bsName, nDef); } inline void UpdateAttributeOrValueBase(const _bstr_t& bstrName, double& nValue) { BSTR bsRes = ReadAttributeBase(bstrName); if (NULL == bsRes) return UpdateValueBase(bstrName, nValue); nValue = XmlUtils::GetDouble(bsRes); SysFreeString(bsRes); } inline void UpdateAttributeOrValue(const CString& strName, double& nValue) { _bstr_t bsName = strName; return UpdateAttributeOrValueBase(bsName, nValue); } inline float ReadAttributeFloatBase(const _bstr_t& bstrName, const float& nDef = 0) { BSTR bsRes = ReadAttributeBase(bstrName); if (NULL == bsRes) return nDef; float nRes = XmlUtils::GetFloat(bsRes); SysFreeString(bsRes); return nRes; } inline float ReadAttributeFloat(const CString& str, const float& nDef = 0) { _bstr_t bsName = str; return ReadAttributeFloatBase(bsName, nDef); } inline float ReadValueFloatBase(const _bstr_t& bstrName, const float& nDef = 0) { BSTR bsRes = ReadNodeTextBase(bstrName); if (NULL == bsRes) return nDef; float nRes = XmlUtils::GetFloat(bsRes); SysFreeString(bsRes); return nRes; } inline float ReadValueFloat(const CString& str, const float& nDef = 0) { _bstr_t bsName = str; return ReadValueFloatBase(bsName, nDef); } inline void UpdateAttributeBase(const _bstr_t& bstrName, float& nValue) { BSTR bsRes = ReadAttributeBase(bstrName); if (NULL == bsRes) return; nValue = XmlUtils::GetFloat(bsRes); SysFreeString(bsRes); } inline void UpdateAttribute(const CString& strName, float& nValue) { _bstr_t bsName = strName; return UpdateAttributeBase(bsName, nValue); } inline void UpdateValueBase(const _bstr_t& bstrName, float& nValue) { BSTR bsRes = ReadNodeTextBase(bstrName); if (NULL == bsRes) return; nValue = XmlUtils::GetFloat(bsRes); SysFreeString(bsRes); } inline void UpdateValue(const CString& strName, float& nValue) { _bstr_t bsName = strName; return UpdateValueBase(bsName, nValue); } inline float ReadAttributeOrValueFloatBase(const _bstr_t& bstrName, const float& nDef = 0) { BSTR bsRes = ReadAttributeBase(bstrName); if (NULL == bsRes) return ReadValueFloatBase(bstrName, nDef); float nRes = XmlUtils::GetFloat(bsRes); SysFreeString(bsRes); return nRes; } inline float ReadAttributeOrValueFloat(const CString& strName, const float& nDef = 0) { _bstr_t bsName = strName; return ReadAttributeOrValueFloatBase(bsName, nDef); } inline void UpdateAttributeOrValueBase(const _bstr_t& bstrName, float& nValue) { BSTR bsRes = ReadAttributeBase(bstrName); if (NULL == bsRes) return UpdateValueBase(bstrName, nValue); nValue = XmlUtils::GetFloat(bsRes); SysFreeString(bsRes); } inline void UpdateAttributeOrValue(const CString& strName, float& nValue) { _bstr_t bsName = strName; return UpdateAttributeOrValueBase(bsName, nValue); } inline CString GetAttributeBase(const _bstr_t& strAttributeName, const CString& strDefaultValue = _T("")) { BSTR bsRes = ReadAttributeBase(strAttributeName); if (NULL == bsRes) return strDefaultValue; CString strRes = (CString)bsRes; SysFreeString(bsRes); return strRes; } inline CString GetAttribute(const CString& strAttributeName, const CString& strDefaultValue = _T("")) { _bstr_t bsName = strAttributeName; return GetAttributeBase(bsName, strDefaultValue); } inline CString GetValueBase(const _bstr_t& strAttributeName, const CString& strDefaultValue = _T("")) { BSTR bsRes = ReadNodeTextBase(strAttributeName); if (NULL == bsRes) return strDefaultValue; CString strRes = (CString)bsRes; SysFreeString(bsRes); return strRes; } inline CString GetValue(const CString& strAttributeName, const CString& strDefaultValue = _T("")) { _bstr_t bsName = strAttributeName; return GetValueBase(bsName); } inline void UpdateAttributeStringBase(const _bstr_t& strName, CString& strVal) { BSTR bsRes = ReadAttributeBase(strName); if (NULL == bsRes) return; strVal = (CString)bsRes; SysFreeString(bsRes); } inline void UpdateAttributeString(const CString& strName, CString& strVal) { _bstr_t bsName = strName; return UpdateAttributeStringBase(bsName, strVal); } inline void UpdateValueStringBase(const _bstr_t& strName, CString& strVal) { BSTR bsRes = ReadNodeTextBase(strName); if (NULL == bsRes) return; strVal = (CString)bsRes; SysFreeString(bsRes); } inline void UpdateValueString(const CString& strName, CString& strVal) { _bstr_t bsName = strName; return UpdateValueStringBase(bsName, strVal); } inline CString GetAttributeOrValueBase(const _bstr_t& strAttributeName, const CString& strDefaultValue = _T("")) { BSTR bsRes = ReadAttributeBase(strAttributeName); if (NULL == bsRes) return GetValueBase(strAttributeName, strDefaultValue); CString strRes = (CString)bsRes; SysFreeString(bsRes); return strRes; } inline CString GetAttributeOrValue(const CString& strAttributeName, const CString& strDefaultValue = _T("")) { _bstr_t bsName = strAttributeName; return GetAttributeOrValueBase(bsName, strDefaultValue); } inline void UpdateAttributeOrValueStringBase(const _bstr_t& strName, CString& strVal) { BSTR bsRes = ReadAttributeBase(strName); if (NULL == bsRes) return UpdateValueStringBase(strName, strVal); strVal = (CString)bsRes; SysFreeString(bsRes); } inline void UpdateAttributeOrValueString(const CString& strName, CString& strVal) { _bstr_t bsName = strName; return UpdateAttributeOrValueStringBase(bsName, strVal); } CString GetXml(const CString& strDefaultValue = _T("")) { if (!IsValid()) return strDefaultValue; return GetNodeXml(m_pXmlNode, strDefaultValue); } CString GetText(const CString& strDefaultValue = _T("")) { if (!IsValid()) return strDefaultValue; return GetNodeText(m_pXmlNode, strDefaultValue); } BOOL GetTextTyped(_variant_t* pVariant, const CString& strNodeType = _T("bin.base64")) { if (!IsValid()) return FALSE; return GetNodeTextTyped(m_pXmlNode, pVariant, strNodeType); } BOOL GetNode(const CString& strSubNodeName, CXmlNode& oXmlNode) { if (!IsValid()) return FALSE; try { _bstr_t bstrNode; bstrNode = strSubNodeName; XML::IXMLDOMNodePtr pNewNode = m_pXmlNode->selectSingleNode(bstrNode); if (NULL != pNewNode) return oXmlNode.FromXmlNode(pNewNode); } catch (...) { } return FALSE; } BOOL GetNodes(const CString& strSubNodesName, CXmlNodes& oXmlNodes) { if (!IsValid()) return FALSE; try { _bstr_t bstrNodes; bstrNodes = strSubNodesName; XML::IXMLDOMNodeListPtr pNewNodes = m_pXmlNode->selectNodes(bstrNodes); if (NULL != pNewNodes) return oXmlNodes.FromXmlNodes(pNewNodes); } catch (...) { } return FALSE; } CString GetTextExt(const CString& strDefaultValue = _T("")) { if (!IsValid()) return strDefaultValue; XML::IXMLDOMNode* pNode = NULL; m_pXmlNode->raw_selectSingleNode(g_cpszXML_TextExt.GetBSTR(), &pNode); if (NULL != pNode) { VARIANT var; pNode->get_nodeValue(&var); pNode->Release(); CString strRet = strDefaultValue; if (VT_BSTR == var.vt) { strRet = var.bstrVal; } VariantClear(&var); return strRet; } return strDefaultValue; } CString GetTextExt2(const CString& strDefaultValue = _T("")) { if (!IsValid()) return strDefaultValue; return GetNodeValueExt(m_pXmlNode, strDefaultValue); } LONG GetTextLenExt() { if (!IsValid()) return 0; return (LONG)m_pXmlNode->xml.length(); } CString GetAttributeExt(const CString& strAttributeName, const CString& strDefaultValue = _T("")) { if (!IsValid()) return strDefaultValue; return GetNodeAttribExt(m_pXmlNode, strAttributeName, strDefaultValue); } CString GetAttributeOrValueExt(const CString& strSubNodeName, const CString& strDefaultValue = _T("")) { CString strAttributeValue = GetAttributeExt(strSubNodeName, strInvalidValue); if (strAttributeValue != strInvalidValue) return strAttributeValue; CXmlNode oNode; if (GetNode(strSubNodeName, oNode)) return oNode.GetTextExt(strDefaultValue); return strDefaultValue; } XML::IXMLDOMNamedNodeMapPtr GetAttributes() { if (NULL == m_pXmlNode) return NULL; return m_pXmlNode->attributes; } }; } namespace XmlUtils { static CStringW RemoveXMLRootNode (const CStringW& aXML) { CStringW sRes; try { XML::IXMLDOMDocument2Ptr pXmlDocument = NULL; if (FAILED(pXmlDocument.CreateInstance(__uuidof(MSXML::DOMDocument60)))) { if (FAILED(pXmlDocument.CreateInstance(__uuidof(MSXML::DOMDocument)))) { pXmlDocument = NULL; } } if (NULL != pXmlDocument) { pXmlDocument->setProperty( _bstr_t(_T("SelectionLanguage")), _variant_t(_T("XPath")) ); } _bstr_t bstrXml; bstrXml = aXML; if (VARIANT_TRUE == pXmlDocument->loadXML(bstrXml)) { XML::IXMLDOMNodeListPtr ptrNodeList = pXmlDocument->childNodes; for (int i = 0; i < ptrNodeList->length;) { XML::IXMLDOMNodePtr ptrNode = ptrNodeList->item[i]; if (NODE_ELEMENT == ptrNode->nodeType) break; pXmlDocument->removeChild(ptrNode); } sRes = pXmlDocument->xml.GetBSTR(); } } catch (...) { } return sRes; } static CStringA ConvertToUTF8 (const CStringW& aUnicodeXML) { CStringW sXML = RemoveXMLRootNode(aUnicodeXML); sXML.Insert(0, L""); int iSize = WideCharToMultiByte (CP_UTF8, 0, sXML, -1, NULL, 0, NULL, NULL); if (iSize <= 0) { ATLTRACE2 ("ConvertToUTF8() error (size detection): 0x%x\n", GetLastError()); return CStringA(sXML); } CStringA sOutXML; if (0 == WideCharToMultiByte (CP_UTF8, 0, sXML, -1, sOutXML.GetBuffer(iSize + 1), iSize, NULL, NULL)) { ATLTRACE2 ("ConvertToUTF8() error (utf-8 conversion): 0x%x\n", GetLastError()); return CStringA(sXML); } sOutXML.ReleaseBuffer(); return sOutXML; } static CStringW ConvertToUnicode (CStringA aAnsiUtf8XML) { CString sRootElement; sRootElement = aAnsiUtf8XML; int nXMLLength = sRootElement.GetLength(); int nStartPos (-1); int nEndPos (-1); CString sEncoding = _T("ascii"); try { if (nXMLLength > 7) { sRootElement.MakeLower(); nStartPos = sRootElement.Find(_T("= 0 && nStartPos < nXMLLength - 2) { nEndPos = sRootElement.Find(_T("?>"), nStartPos + 5); if (nEndPos > nStartPos && nEndPos < nXMLLength) { CString sXMLNode = sRootElement.Mid (nStartPos, nEndPos - nStartPos + 2); sXMLNode += _T(""); XML::IXMLDOMDocument2Ptr pXmlDocument = NULL; if (FAILED(pXmlDocument.CreateInstance(__uuidof(MSXML::DOMDocument60)))) { if (FAILED(pXmlDocument.CreateInstance(__uuidof(MSXML::DOMDocument)))) { pXmlDocument = NULL; } } if (NULL != pXmlDocument) { pXmlDocument->setProperty( _bstr_t(_T("SelectionLanguage")), _variant_t(_T("XPath")) ); } _bstr_t bstrRootXml; bstrRootXml = sXMLNode; if (VARIANT_TRUE == pXmlDocument->loadXML(bstrRootXml)) { XML::IXMLDOMNodeListPtr ptrNodeList = pXmlDocument->childNodes; for (int i = 0; i < ptrNodeList->length; i++) { XML::IXMLDOMNodePtr ptrNode = ptrNodeList->item[i]; CString sName; sName = ptrNode->nodeName.GetBSTR(); sName.MakeLower(); if (_T("xml") == sName) { sEncoding = XmlUtils::GetNodeAttrib(ptrNode, _T("encoding"), _T("ascii")); break; } } } } } } } catch (...) { return CStringW (aAnsiUtf8XML); } sEncoding.MakeLower(); CStringW sw; if (_T("utf-8") == sEncoding) { int nSize = MultiByteToWideChar(CP_UTF8, 0, aAnsiUtf8XML.GetBuffer(), -1, NULL, 0); MultiByteToWideChar(CP_UTF8, 0, aAnsiUtf8XML.GetBuffer(), -1, sw.GetBuffer(nSize + 1), nSize); sw.ReleaseBuffer(); } else { int nSize = MultiByteToWideChar(CP_ACP, 0, aAnsiUtf8XML.GetBuffer(), -1, NULL, 0); MultiByteToWideChar(CP_ACP, 0, aAnsiUtf8XML.GetBuffer(), -1, sw.GetBuffer(nSize + 1), nSize); sw.ReleaseBuffer(); } return RemoveXMLRootNode(sw); } }