Ejemplo n.º 1
0
BOOL CKADmerge::HasNode(IXMLDOMNode * pXMLNode, string sPatternString, IXMLDOMNode ** pXMLTarget)
{
    BOOL bRet = FALSE;
    HRESULT hRes = 0;
    LONG lListLength = 0;

    IXMLDOMNodeList * pXMLNodeList = NULL;
    _bstr_t bPatternString(sPatternString.c_str());
    hRes = pXMLNode->selectNodes(bPatternString, &pXMLNodeList);

    if(SUCCEEDED(hRes))
    {
        hRes = pXMLNodeList->get_length(&lListLength);
        if(lListLength)
        {
            hRes = pXMLNodeList->nextNode(pXMLTarget);
            bRet = TRUE;
        }
        else
        {
            string str01 = GetName(pXMLNode);
            string str02 = GetName(*pXMLTarget);
            bRet = FALSE;
        }
    }

    if(pXMLNodeList)
        pXMLNodeList->Release();

    return bRet;
}
Ejemplo n.º 2
0
// FindElements
UINT COpcXmlDocument::FindElements(const COpcString& cXPath, COpcXmlElementList& cElements)
{
    cElements.RemoveAll();

    // check if document exists.
    if (m_ipDocument == NULL)
    {
        return 0;
    }

    // search for matching nodes.
    IXMLDOMNodeList* ipNodes = NULL;

    BSTR bstrQuery = SysAllocString(cXPath);
    HRESULT hResult = m_ipDocument->selectNodes(bstrQuery, &ipNodes);
    SysFreeString(bstrQuery);

    if (FAILED(hResult))
    {
        return 0;
    }

    // add found nodes to element list.
    do
    {
        IXMLDOMNode* ipNode = NULL;

        hResult = ipNodes->nextNode(&ipNode);

        if (hResult != S_OK || ipNode == NULL)
        {
            break;
        }

        COpcXmlElement cElement(ipNode);
        ipNode->Release();

        if (cElement != NULL)
        {
            cElements.Append(cElement);
        }
    }
    while (SUCCEEDED(hResult));

    if (ipNodes != NULL)
    {
        ipNodes->Release();
    }

    // return the number of elements found.
    return cElements.GetSize();
}
Ejemplo n.º 3
0
/*
	Function name	: CXML::GetRootNode
	Description	    : This helper function retrieves the DOM pointer to the root node
	Return type		: bool 
	Argument        : CString csRootTagName
	Tested			: Ok
*/
bool CXML::GetRootNode(CString csRootTagName)
{
	IXMLDOMNodeList * pINodeList = NULL;

	_bstr_t bstrRootTagName(csRootTagName);

	m_hr = m_pXMLDoc->getElementsByTagName(bstrRootTagName ,&pINodeList);

	if(!SUCCEEDED(m_hr))
		return false;

	m_hr = pINodeList->nextNode(&m_pIRootNode);
	pINodeList->Release();
	if(!SUCCEEDED(m_hr))
		return false;

	return true;
}
Ejemplo n.º 4
0
IXMLDOMNode *CXML::NextChildNode(IXMLDOMNode **ppNode)
{
	if(!(*ppNode))
		return NULL;

	IXMLDOMNode * pNode = NULL;
	IXMLDOMNodeList * pChildList = NULL;
	
	// Get the list of child nodes of the current node

	m_hr = (*ppNode)->get_childNodes(&pChildList);
	if (!SUCCEEDED(m_hr))
		return NULL;
	// loop through the childs
	DOMNodeType nodeType;
	while(true)
	{
		// Get the node type of each child, if it is of NODE_ELEMENT type set it as current node
		m_hr = pChildList->nextNode(&pNode);
		if(!SUCCEEDED(m_hr))
		{
			pChildList->Release();
			return NULL;
		}
		if(!pNode) break;
		m_hr = pNode->get_nodeType(&nodeType);
		if(!SUCCEEDED(m_hr))
		{
			pChildList->Release();
			pNode->Release();
			return NULL;
		}

		if(nodeType == NODE_ELEMENT)
			break;
		if(pNode)
			pNode->Release();
	}

	if(pChildList)
		pChildList->Release();

	return pNode;
}
Ejemplo n.º 5
0
/*
	Function name	: CXML::ReplaceNodeText
	Description	    : This Helper function replaces the existing text with the given text of 
					: the given node. 
	Return type		: bool 
	Argument        : IXMLDOMNode **pNode
	Argument        : CString &rcsNodeText
	Tested			: 
*/
bool CXML::ReplaceNodeText(IXMLDOMNode **pNode,CString &rcsNodeText)
{
	IXMLDOMText  * pTextNode = NULL;
	if(!(*pNode))
		return false;

	IXMLDOMNode * pTempNode = NULL;
	DOMNodeType nodeType;
	IXMLDOMNode * pINewNode = NULL;
	IXMLDOMNode * pIOldNode = NULL;
	IXMLDOMNodeList * pChildList = NULL;
	long nLen = 0,i=0;


	_bstr_t bstrData(rcsNodeText);

	m_hr = m_pXMLDoc->createTextNode(bstrData,&pTextNode);
	if(!SUCCEEDED(m_hr) || !pTextNode)
		goto on_Error;	


	m_hr = (*pNode)->get_childNodes(&pChildList);
	if(!SUCCEEDED(m_hr) || !pChildList)
		goto on_Error;
	
	m_hr = pChildList->get_length(&nLen);
	if(!SUCCEEDED(m_hr))
		goto on_Error;

	if(nLen == 0)	// no childs, if the tag is empty
	{
		bool bRet = CreateNodeText(pNode,rcsNodeText);
		if(pChildList)
			pChildList->Release();
		if(pTextNode)
			pTextNode->Release();
		return bRet;		
	}

	for(i =0; i< nLen;++i)
	{
		m_hr = pChildList->nextNode(&pTempNode);
		if(!SUCCEEDED(m_hr))
			goto on_Error;

		m_hr = pTempNode->get_nodeType(&nodeType);
		if(!SUCCEEDED(m_hr))
			goto on_Error;

		if(nodeType == NODE_TEXT)
			break;

		if(pTempNode)
		{
			pTempNode->Release();
			pTempNode = NULL;
		}
	}

	m_hr = (*pNode)->replaceChild(pTextNode,pTempNode,&pINewNode);
	if(!SUCCEEDED(m_hr) || !pINewNode)
			goto on_Error;

	if(pChildList)
		pChildList->Release();
	if(pTextNode)
		pTextNode->Release();
	if(pINewNode)
		pINewNode->Release();
	if(pTempNode)
		pTempNode->Release();

	return true;


on_Error:	// Release all the References

	if(pChildList)
		pChildList->Release();
	if(pTextNode)
		pTextNode->Release();
	if(pINewNode)
		pINewNode->Release();
	if(pTempNode)
		pTempNode->Release();
	
	return false; 
}
Ejemplo n.º 6
0
bool CXML::NextChildNode()
{
	if(!m_pICurrentNode)
		return false;

	IXMLDOMNode * pNode = NULL;
	IXMLDOMNode * pITempNode = m_pICurrentNode;
	pITempNode->AddRef();

	IXMLDOMNodeList * pChildList = NULL;
	
	// Get the list of child nodes of the current node

	m_hr = pITempNode->get_childNodes(&pChildList);
	pITempNode->Release();
	if (!SUCCEEDED(m_hr))
		return false;
	// loop through the childs
	DOMNodeType nodeType;
	while(true)
	{
		// Get the node type of each child, if it is of NODE_ELEMENT type set it as current node
		m_hr = pChildList->nextNode(&pNode);
		if(!SUCCEEDED(m_hr))
		{
			pChildList->Release();
			return false;
		}
		if(!pNode) break;
		m_hr = pNode->get_nodeType(&nodeType);
		if(!SUCCEEDED(m_hr))
		{
			pChildList->Release();
			pNode->Release();
			return false;
		}

		if(nodeType == NODE_ELEMENT)
			break;
		if(pNode)
			pNode->Release();
	}

	if(pChildList)
		pChildList->Release();

	if(pNode)
	{
		if(m_pICurrentNode)
		{
			m_pICurrentNode->Release();
			m_pICurrentNode = NULL;
		}

		m_pICurrentNode = pNode;
		m_pICurrentNode->AddRef();

		pNode->Release();
		return true;
	}
	return false;
	
}
Ejemplo n.º 7
0
// эта функция, если значения нет (или тип некорректный) *value НЕ трогает
bool SettingsXML::Load(const wchar_t *regName, wchar_t **value)
{
	bool lbRc = false;
	HRESULT hr = S_OK;
	IXMLDOMNode* pChild = NULL;
	IXMLDOMNamedNodeMap* pAttrs = NULL;
	IXMLDOMAttribute *pIXMLDOMAttribute = NULL;
	IXMLDOMNode *pNode = NULL;
	IXMLDOMNodeList* pList = NULL;
	BSTR bsType = NULL;
	BSTR bsData = NULL;
	size_t nLen = 0;

	//if (*value) {free(*value); *value = NULL;}

	if (mp_Key)
		pChild = FindItem(mp_Key, L"value", regName, false);

	if (!pChild)
		return false;

	hr = pChild->get_attributes(&pAttrs);

	if (SUCCEEDED(hr) && pAttrs)
	{
		bsType = GetAttr(pChild, pAttrs, L"type");
	}

	if (SUCCEEDED(hr) && bsType)
	{
		if (!lstrcmpi(bsType, L"multi"))
		{
			// Тут значения хранятся так:
			//<value name="CmdLineHistory" type="multi">
			//	<line data="C:\Far\Far.exe"/>
			//	<line data="cmd"/>
			//</value>
			wchar_t *pszData = NULL, *pszCur = NULL;
			size_t nMaxLen = 0, nCurLen = 0;
			long nCount = 0;

			if (pAttrs) { pAttrs->Release(); pAttrs = NULL; }

			// Получить все дочерние элементы нужного типа
			bsData = ::SysAllocString(L"line");
			hr = pChild->selectNodes(bsData, &pList);
			::SysFreeString(bsData); bsData = NULL;

			if (SUCCEEDED(hr) && pList)
			{
				hr = pList->get_length(&nCount);

				if (SUCCEEDED(hr) && (nCount > 0))
				{
					HEAPVAL;
					nMaxLen = ((MAX_PATH+1) * nCount) + 1;
					pszData = (wchar_t*)malloc(nMaxLen * sizeof(wchar_t));
					pszCur = pszData;
					pszCur[0] = 0; pszCur[1] = 0;
					nCurLen = 2; // сразу посчитать DoubleZero
					HEAPVAL;
				}
			}

			if (SUCCEEDED(hr) && pList)
			{
				hr = pList->reset();

				while ((hr = pList->nextNode(&pNode)) == S_OK && pNode)
				{
					bsData = GetAttr(pNode, L"data");
					pNode->Release(); pNode = NULL;

					if (SUCCEEDED(hr) && bsData)
					{
						nLen = _tcslen(bsData) + 1;

						if ((nCurLen + nLen) > nMaxLen)
						{
							// Нужно пересоздать!
							nMaxLen = nCurLen + nLen + MAX_PATH + 1;
							wchar_t *psz = (wchar_t*)malloc(nMaxLen * sizeof(wchar_t));
							_ASSERTE(psz);

							if (!psz) break;  // Не удалось выделить память!

							wmemmove(psz, pszData, nCurLen);
							pszCur = psz + (pszCur - pszData);
							HEAPVAL;
							free(pszData);
							pszData = psz;
							HEAPVAL;
						}

						lstrcpy(pszCur, bsData);
						pszCur += nLen; // указатель - на место для следующей строки
						nCurLen += nLen;
						*pszCur = 0; // ASCIIZZ
						HEAPVAL;
						::SysFreeString(bsData); bsData = NULL;
					}
				}

				pList->Release(); pList = NULL;
			}

			// значит что-то прочитать удалось
			if (pszData)
			{
				if (*value) {free(*value); *value = NULL;}
				*value = pszData;
				lbRc = true;
			}
		}
		else if (!lstrcmpi(bsType, L"string"))
		{
			bsData = GetAttr(pChild, pAttrs, L"data");

			if (SUCCEEDED(hr) && bsData)
			{
				nLen = _tcslen(bsData);
				if (!*value || (_tcslen(*value) <= nLen))
				{
					*value = (wchar_t*)realloc(*value, (nLen+2)*sizeof(wchar_t));
				}
				if (*value)
				{
					lstrcpy(*value, bsData);
					(*value)[nLen] = 0; // уже должен быть после lstrcpy
					(*value)[nLen+1] = 0; // ASCIIZZ
					lbRc = true;
				}
			}
		}

		// Все остальные типы - не интересуют. Нам нужны только строки
	}

	if (bsType) { ::SysFreeString(bsType); bsType = NULL; }

	if (bsData) { ::SysFreeString(bsData); bsData = NULL; }

	if (pChild) { pChild->Release(); pChild = NULL; }

	if (pAttrs) { pAttrs->Release(); pAttrs = NULL; }

	//if (!lbRc)
	//{
	//	_ASSERTE(*value == NULL);
	//	*value = (wchar_t*)malloc(sizeof(wchar_t)*2);
	//	(*value)[0] = 0; (*value)[1] = 0; // На случай REG_MULTI_SZ
	//}

	return lbRc;
}
Ejemplo n.º 8
0
IXMLDOMNode* SettingsXML::FindItem(IXMLDOMNode* apFrom, const wchar_t* asType, const wchar_t* asName, bool abAllowCreate)
{
	HRESULT hr = S_OK;
	IXMLDOMNodeList* pList = NULL;
	IXMLDOMNode* pChild = NULL;
	IXMLDOMNamedNodeMap* pAttrs = NULL;
	IXMLDOMAttribute *pIXMLDOMAttribute = NULL;
	IXMLDOMNode *pIXMLDOMNode = NULL;
	IXMLDOMNode *pName = NULL;
	BSTR bsText = NULL;
	BSTR bsCheck = NULL;
	DOMNodeType nodeTypeCheck = NODE_INVALID;
	BOOL lbEmpty = TRUE;
	int iLastIndent = 1;

	// Получить все дочерние элементы нужного типа
	if (apFrom == NULL)
	{
		hr = S_FALSE;
	}
	else
	{
		long lFound = 0;
		// key[@name="abc"], but it is case-sensitive, and may fails in theory
		bsText = lstrmerge(asType, L"[@name=\"", asName, L"\"]");
		hr = apFrom->selectNodes(bsText, &pList);
		if (SUCCEEDED(hr) && pList)
		{
			hr = pList->get_length(&lFound);
			if (FAILED(hr) || (lFound < 1))
			{
				SafeRelease(pList);
			}
		}
		SafeFree(bsText);
		// May be case-insensitive search will be succeeded?
		// However, it is very slow
		if (!pList)
		{
			bsText = ::SysAllocString(asType);
			hr = apFrom->selectNodes(bsText, &pList);
			::SysFreeString(bsText); bsText = NULL;
		}
	}

	if (SUCCEEDED(hr) && pList)
	{
		hr = pList->reset();

		while ((hr = pList->nextNode(&pIXMLDOMNode)) == S_OK && pIXMLDOMNode)
		{
			lbEmpty = FALSE;
			hr = pIXMLDOMNode->get_attributes(&pAttrs);

			if (SUCCEEDED(hr) && pAttrs)
			{
				bsText = GetAttr(pIXMLDOMNode, pAttrs, L"name");

				if (bsText)
				{
					if (lstrcmpi(bsText, asName) == 0)
					{
						::SysFreeString(bsText); bsText = NULL;
						pChild = pIXMLDOMNode; pIXMLDOMNode = NULL;
						break;
					}

					::SysFreeString(bsText); bsText = NULL;
				}
			}

			pIXMLDOMNode->Release(); pIXMLDOMNode = NULL;
		}

		pList->Release();
		//pList = NULL; -- для отладки
	}

	if (lbEmpty && abAllowCreate && (asType[0] == L'k'))
	{
		bsText = ::SysAllocString(L"value");
		hr = apFrom->selectNodes(bsText, &pList);
		::SysFreeString(bsText); bsText = NULL;
		if (SUCCEEDED(hr) && pList)
		{
			hr = pList->reset();
			if ((hr = pList->nextNode(&pIXMLDOMNode)) == S_OK && pIXMLDOMNode)
			{
				lbEmpty = FALSE;
				pIXMLDOMNode->Release(); pIXMLDOMNode = NULL;
			}
			pList->Release();
			//pList = NULL; -- для отладки
		}
	}

	if (!pChild && abAllowCreate)
	{
		if (asType[0] == L'k')
		{
			hr = apFrom->get_lastChild(&pChild);
			if (SUCCEEDED(hr) && pChild)
			{
				hr = pChild->get_nodeType(&nodeTypeCheck);
				if (SUCCEEDED(hr) && (nodeTypeCheck == NODE_TEXT))
				{
					hr = pChild->get_text(&bsCheck);
					if (SUCCEEDED(hr) && bsCheck)
					{
						iLastIndent = 0;
						LPCWSTR pszTabs = bsCheck;
						while (*pszTabs)
						{
							if (*(pszTabs++) == L'\t')
								iLastIndent++;
						}
						::SysFreeString(bsCheck); bsCheck = NULL;
					}
				}
			}
			SafeRelease(pChild);
		}

		VARIANT vtType; vtType.vt = VT_I4;
		vtType.lVal = NODE_ELEMENT;
		bsText = ::SysAllocString(asType);
		hr = mp_File->createNode(vtType, bsText, L"", &pChild);
		::SysFreeString(bsText); bsText = NULL;

		if (SUCCEEDED(hr) && pChild)
		{
			if (SetAttr(pChild, L"name", asName))
			{
				if (asType[0] == L'k')
				{
					AppendNewLine(pChild);
					mb_KeyEmpty = true;
					TouchKey(pChild);
				}

				if (asType[0] == L'k')
				{
					//if (mb_KeyEmpty)
					//AppendIndent(apFrom, lbEmpty ? (mi_Level-1) : mi_Level);
					AppendIndent(apFrom, (mi_Level-iLastIndent));
				}
				else if (mb_KeyEmpty)
				{
					AppendIndent(apFrom, !lbEmpty ? (mi_Level-1) : mi_Level);
				}
				else
				{
					AppendIndent(apFrom, 1);
				}
				hr = apFrom->appendChild(pChild, &pIXMLDOMNode);
				pChild->Release(); pChild = NULL;

				if (FAILED(hr))
				{
					pAttrs->Release(); pAttrs = NULL;
				}
				else
				{
					pChild = pIXMLDOMNode;
					pIXMLDOMNode = NULL;
				}

				AppendNewLine(apFrom);
				AppendIndent(apFrom, mi_Level-1);
				if ((asType[0] != L'k') && mb_KeyEmpty)
					mb_KeyEmpty = false;
			}
			else
			{
				pChild->Release(); pChild = NULL;
			}
		}
	}

	return pChild;
}
Ejemplo n.º 9
0
string CKADmerge::GetPatternString(IXMLDOMNode * pXMLNode, BOOL bQuery)
{
    HRESULT hRes = 0;
    string sPatternString = "";
    string sElementName;

    if(pXMLNode)
    {
        // retrieve node name
        sElementName = GetName(pXMLNode);
        sPatternString = sElementName;

        if(SUCCEEDED(hRes))
        {
            // retrieve all attributes
            IXMLDOMNodeList * pNodeList = NULL;
            BSTR bPatternString = NULL;
            bPatternString = ::SysAllocString(L"@*");
            _bstr_t b2PatternString(bPatternString);
            hRes = pXMLNode->selectNodes(bPatternString, &pNodeList);
            ::SysFreeString(bPatternString);

            LONG lListLength = 0;
            hRes = pNodeList->get_length(&lListLength);

            if(SUCCEEDED(hRes) && lListLength)
            {
                // retrive attribute names
                IXMLDOMNode * pCurrentNode = NULL;
                hRes = pNodeList->nextNode(&pCurrentNode);
                string sAttributeName;
                while(pCurrentNode != NULL)
                {
                    // attach attibute names and values to pattern string
                    sAttributeName = GetName(pCurrentNode);

                    if(!bQuery)
                    {
                        // all attributes
                        if(sPatternString.find("[") == -1)
                        {
                            sPatternString += "[";
                        }
                        else
                        {
                            sPatternString += " and " ;
                        }
                        sPatternString += "@" + sAttributeName;
                        sPatternString += "=\"" + ExpandBackslash(GetValue(pCurrentNode)) + "\"";
                    }
                    else
                    {
                        // just "primary key" (only first attribute)
                        if(sPatternString.find("[") == -1)
                        {
                            sPatternString += "[";
                        }
                        sPatternString += "@" + sAttributeName;
                        sPatternString += "=\"" + ExpandBackslash(GetValue(pCurrentNode)) + "\"";

                        break;
                    }
                    hRes = pNodeList->nextNode(&pCurrentNode);
                }
                if(sPatternString.find("[") != -1)
                {
                    sPatternString += "]";
                }
            }
            if(pNodeList)
                pNodeList->Release();
        }
    }

    return sPatternString;
}
Ejemplo n.º 10
0
HRESULT CKADmerge::GetKADFilenames(string * sFilenames[], LONG &lLength, string sLogFile)
{
    HRESULT hRes = S_FALSE;

    if(sLogFile != "")
    {
        // open log file
        OpenLog(sLogFile, sDescription + " GetKADFileNames");
    }

    IXMLDOMNode * pXMLRoot = NULL;
    hRes = GetRootElement(m_pXMLKad, &pXMLRoot);

    if(hRes == S_OK)
    {
        // find elements
        IXMLDOMNodeList * pElemList = NULL;
        _bstr_t bPatternString("/KAD4CE/KERNEL/ADDON[@KADFILE]");
        hRes = pXMLRoot->selectNodes(bPatternString, &pElemList);

        if(SUCCEEDED(hRes))
        {
            LONG lElements = 0;
            pElemList->get_length(&lElements);

            (*sFilenames) = new string[lElements];

            IXMLDOMNode * pCurrentElem = NULL;
            hRes = pElemList->nextNode(&pCurrentElem);
            int i = 0;
            while(pCurrentElem != NULL)
            {
                // find 'KADFILE' attribute
                IXMLDOMNodeList * pAttrList = NULL;
                _bstr_t bPatternString("@KADFILE");
                hRes = pCurrentElem->selectNodes(bPatternString, &pAttrList);

                if(SUCCEEDED(hRes))
                {
                    LONG lAtributes = 0;
                    pAttrList->get_length(&lAtributes);

                    IXMLDOMNode * pCurrentAttr = NULL;
                    hRes = pAttrList->nextNode(&pCurrentAttr);
                    if(lAtributes == 1)
                    {
                        (*sFilenames)[i++] = GetValue(pCurrentAttr);
                    }
                    if(pCurrentAttr)
                        pCurrentAttr->Release();
                }
                hRes = pElemList->nextNode(&pCurrentElem);
                if(pAttrList)
                    pAttrList->Release();
            }
            lLength = i;
            hRes = S_OK;

            if(pCurrentElem)
                pCurrentElem->Release();
        }

        if(pXMLRoot)
            pXMLRoot->Release();
        if(pElemList)
            pElemList->Release();
    }

    if(hRes == S_OK)
    {
        Log("GetKADFilenames:");
        for(int i = 0; i < (int)lLength; i++)
        {
            Log((*sFilenames)[i]);
        }
    }

    // close log file
    CloseLog();

    return hRes;
}
Ejemplo n.º 11
0
HRESULT CKADmerge::CopyNode(IXMLDOMNode ** pXMLDest, IXMLDOMNode ** pXMLSrc, BOOL bOverwrite, string sPath)
{
    HRESULT hRes = 0;

    IXMLDOMNodeList * pNodeList = NULL;

    if(*pXMLDest == NULL || *pXMLSrc == NULL)
    {
        Log("ERROR: CopyNode " + GetName(*pXMLSrc) + " to " + GetName(*pXMLDest));
        hRes = S_FALSE;
        return hRes;
    }

    hRes = (*pXMLSrc)->get_childNodes(&pNodeList);

    if(SUCCEEDED(hRes))
    {
        LONG lListLength = 0;
        hRes = pNodeList->get_length(&lListLength);

        IXMLDOMNode * pCurrentNode = NULL;
        hRes = pNodeList->nextNode(&pCurrentNode);

        while(pCurrentNode != NULL)
        {
            // iterate through the xml tree
            string sPatternString = GetPatternString(pCurrentNode, TRUE);

            IXMLDOMNode * pDestNode = NULL;
            BOOL bHasNode = HasNode(*pXMLDest, sPatternString, &pDestNode);
            if(bHasNode && (!m_Overwriteable[GetName(pCurrentNode)] || !bOverwrite ))
            {
                // copy child elements
                CopyNode(&pDestNode, &pCurrentNode, bOverwrite, sPath + "/" + sPatternString);
            }
            else if(bHasNode && m_Overwriteable[GetName(pCurrentNode)] && bOverwrite)
            {
                // compare element
                sPatternString = GetPatternString(pCurrentNode, TRUE);
                bHasNode = HasNode(*pXMLDest, sPatternString, &pDestNode);

                if(bHasNode)
                {
                    sPatternString = GetPatternString(pCurrentNode, FALSE);
                    bHasNode = HasNode(*pXMLDest, sPatternString, &pDestNode);

                    if(!bHasNode)
                    {
                        // replace element
                        IXMLDOMNode * pNewNode = NULL;
                        IXMLDOMNode * pXMLOldChild = NULL;

                        hRes = pCurrentNode->cloneNode(VARIANT_TRUE, &pNewNode);
                        hRes = (*pXMLDest)->replaceChild(pNewNode,          // new child
                                                         pDestNode,         // old child
                                                         &pXMLOldChild);    // out old child

                        // log changes
                        Log("Replace Element: " + sPath + "/" + sPatternString);

                        if(pNewNode)
                            pNewNode->Release();
                        if(pXMLOldChild)
                            pXMLOldChild->Release();
                        m_bIsDirty = TRUE;
                    }
                }
            }
            else if(!bHasNode)
            {
                // attach entire sub tree
                IXMLDOMNode * pDestNode = NULL;
                IXMLDOMNode * pXMLNewChild = NULL;
                hRes = pCurrentNode->cloneNode(VARIANT_TRUE, &pDestNode);
                hRes = (*pXMLDest)->appendChild(pDestNode,          // new child
                                                &pXMLNewChild);     // out new child

                // log changes
                sPatternString = GetPatternString(pCurrentNode, FALSE);
                Log("Attach Element: " + sPath + "/" + sPatternString);

                if(pDestNode)
                    pDestNode->Release();
                if(pXMLNewChild)
                    pXMLNewChild->Release();
                m_bIsDirty = TRUE;
            }

            hRes = pNodeList->nextNode(&pCurrentNode);
        }
    }

    return hRes;
}
Ejemplo n.º 12
0
IXMLDOMNode* SettingsXML::FindItem(IXMLDOMNode* apFrom, const wchar_t* asType, const wchar_t* asName, bool abAllowCreate)
{
	HRESULT hr = S_OK;
	IXMLDOMNodeList* pList = NULL;
	IXMLDOMNode* pChild = NULL;
	IXMLDOMNamedNodeMap* pAttrs = NULL;
	IXMLDOMAttribute *pIXMLDOMAttribute = NULL;
	IXMLDOMNode *pIXMLDOMNode = NULL;
	IXMLDOMNode *pName = NULL;
	BSTR bsText = NULL;
	BOOL lbEmpty = TRUE;

	// Получить все дочерние элементы нужного типа
	if (apFrom == NULL)
	{
		hr = S_FALSE;
	}
	else
	{
		bsText = ::SysAllocString(asType);
		hr = apFrom->selectNodes(bsText, &pList);
		::SysFreeString(bsText); bsText = NULL;
	}

	if (SUCCEEDED(hr) && pList)
	{
		hr = pList->reset();

		while((hr = pList->nextNode(&pIXMLDOMNode)) == S_OK && pIXMLDOMNode)
		{
			lbEmpty = FALSE;
			hr = pIXMLDOMNode->get_attributes(&pAttrs);

			if (SUCCEEDED(hr) && pAttrs)
			{
				bsText = GetAttr(pIXMLDOMNode, pAttrs, L"name");

				if (bsText)
				{
					if (lstrcmpi(bsText, asName) == 0)
					{
						::SysFreeString(bsText); bsText = NULL;
						pChild = pIXMLDOMNode; pIXMLDOMNode = NULL;
						break;
					}

					::SysFreeString(bsText); bsText = NULL;
				}
			}

			pIXMLDOMNode->Release(); pIXMLDOMNode = NULL;
		}

		pList->Release();
		//pList = NULL; -- для отладки
	}
	
	if (lbEmpty && abAllowCreate && (asType[0] == L'k'))
	{
		bsText = ::SysAllocString(L"value");
		hr = apFrom->selectNodes(bsText, &pList);
		::SysFreeString(bsText); bsText = NULL;
		if (SUCCEEDED(hr) && pList)
		{
			hr = pList->reset();
			if ((hr = pList->nextNode(&pIXMLDOMNode)) == S_OK && pIXMLDOMNode)
			{
				lbEmpty = FALSE;
				pIXMLDOMNode->Release(); pIXMLDOMNode = NULL;
			}
			pList->Release();
			//pList = NULL; -- для отладки
		}
	}

	if (!pChild && abAllowCreate)
	{
		VARIANT vtType; vtType.vt = VT_I4;
		vtType.lVal = NODE_ELEMENT;
		bsText = ::SysAllocString(asType);
		hr = mp_File->createNode(vtType, bsText, L"", &pChild);
		::SysFreeString(bsText); bsText = NULL;

		if (SUCCEEDED(hr) && pChild)
		{
			if (SetAttr(pChild, L"name", asName))
			{
				if (asType[0] == L'k')
				{
					AppendNewLine(pChild);
					mb_KeyEmpty = true;
				}

				if (asType[0] == L'k')
				{
					//if (mb_KeyEmpty)
					//AppendIndent(apFrom, lbEmpty ? (mi_Level-1) : mi_Level);
					AppendIndent(apFrom, (mi_Level-1));
				}
				else if (mb_KeyEmpty)
				{
					AppendIndent(apFrom, !lbEmpty ? (mi_Level-1) : mi_Level);
				}
				else
				{
					AppendIndent(apFrom, 1);
				}
				hr = apFrom->appendChild(pChild, &pIXMLDOMNode);
				pChild->Release(); pChild = NULL;

				if (FAILED(hr))
				{
					pAttrs->Release(); pAttrs = NULL;
				}
				else
				{
					pChild = pIXMLDOMNode;
					pIXMLDOMNode = NULL;
				}

				AppendNewLine(apFrom);
				AppendIndent(apFrom, mi_Level-1);
				if ((asType[0] != L'k') && mb_KeyEmpty)
					mb_KeyEmpty = false;
			}
			else
			{
				pChild->Release(); pChild = NULL;
			}
		}
	}

	return pChild;
}