Ejemplo n.º 1
0
std::wstring CXmlNode::GetAttribute(LPCTSTR lpAttributeName)
{
	IXMLDOMNamedNodeMap* lpNamedNodeMap;
	IXMLDOMNode* lpXMLNode;
	BSTR bstrValue;
	std::wstring strValue;
	HRESULT hr;

	if (NULL == lpAttributeName || NULL == m_pXMLNode)
		return _T("");

	lpNamedNodeMap = NULL;
	hr = m_pXMLNode->get_attributes(&lpNamedNodeMap);
	if (hr == S_OK)
	{
		lpXMLNode = NULL;
		hr = lpNamedNodeMap->getNamedItem((WCHAR *)lpAttributeName, &lpXMLNode);
		if (hr == S_OK)
		{
			hr = lpXMLNode->get_text(&bstrValue);
			if (hr == S_OK)
			{
				strValue = (WCHAR *)bstrValue;
				::SysFreeString(bstrValue);
			}
			lpXMLNode->Release();
		}
		lpNamedNodeMap->Release();
	}

	return strValue;
}
Ejemplo n.º 2
0
/*
	 Function name		: CXML::CreateTextNode
	 Description	    : This helper function create an attribute to the node supplied as argumnet
	 Return type		: bool 
	 Argument			: IXMLDOMNode **pParentNode
 	 Argument			: CString csAttribute
 	 Argument			: CString csValue
 */	
bool CXML::RemoveAttributeNode(IXMLDOMNode **pParentNode,CString csAttribute)
{
	IXMLDOMNode * pNode = NULL;
	if(csAttribute.IsEmpty())
		return false;

	if(!(*pParentNode))
		return false;
	
	IXMLDOMNamedNodeMap * pAttributes = NULL;
	m_hr = (*pParentNode)->get_attributes(&pAttributes);
	
	if(!SUCCEEDED(m_hr) || !pAttributes)
		return false;

	IXMLDOMNode *pRemovedNode = NULL;
	_bstr_t bstrAttribute(csAttribute);
	
	m_hr = pAttributes->removeNamedItem(bstrAttribute,&pRemovedNode);
	
	pAttributes->Release();
	if(!SUCCEEDED(m_hr) || !pRemovedNode)
		return false;

	pRemovedNode->Release();
	return true;
}
Ejemplo n.º 3
0
bool CXML::GetNodeAttributeValue(IXMLDOMNode ** ppNode,CString csAttributeName,CString &rcsValue)
{

	IXMLDOMNode *pNodeAttribute = NULL;
	IXMLDOMNamedNodeMap *pNodeMap = NULL;
	CString csTemp;

	if(!ppNode || !(*ppNode))
		return false;

	m_hr =	(*ppNode)->get_attributes(&pNodeMap);

	if (SUCCEEDED(m_hr) == 0 || pNodeMap == NULL) 
		return false;

	_bstr_t bstrAttributeName(csAttributeName);

	m_hr =	pNodeMap->getNamedItem (bstrAttributeName,&pNodeAttribute);	
	pNodeMap->Release();
	if (SUCCEEDED(m_hr) == 0 || (pNodeAttribute == NULL))	
		return false;
	
	_variant_t vtAttributeVal;
	m_hr =	pNodeAttribute->get_nodeValue(&vtAttributeVal);

	pNodeAttribute->Release();

	if (SUCCEEDED(m_hr) == 0)
		return false;
        
	rcsValue = vtAttributeVal.bstrVal;
	return true;	
}
Ejemplo n.º 4
0
///////////////////////////////////////////////////////
// RADEventsXML::ConstructEventNode
//
// Creates an XMLEvent node from a RADEvent object
//
// An example XML node as text:
//	<Event num="0057"
//	starttime="0000020010826175602000" endtime="0000020010826175827000"
//	maxtime="0000020010826175702000"
//	sum="10941.0" maxvalue="84"
//	starttimedisplay="2001.08.26 - 17:56:02"
//	endtimedisplay="2001.08.26 - 17:58:27"
//	maxtimedisplay="2001.08.26 - 17:57:02"
//	etype="Channel"
//	stationname="GRAND 2" />
//
// Note: the text attribute values are created from the strings
// on the RADEvent object.
// 
// Input:
//	pEvent	- the RADEvent instance
//
// Returns:
//	IXMLDOMElement: the constructed Event node,
//	or a NULL pointer if processing failed.
//
///////////////////////////////////////////////////////
IXMLDOMElement* RADEventsXML::ConstructEventNode(RADEvent* pEvent)
{
	IXMLDOMElement *pEventElement = NULL;
	_variant_t var1;
	_bstr_t bstr1;
	HRESULT hr;

	IXMLDOMAttribute *pAttNode=NULL;
	IXMLDOMNode *pIXMLDOMNode=NULL;
	IXMLDOMNamedNodeMap* pAttMap = NULL;
	int j;

	// construct <Event>
	bstr1 = "Event";
	HRCALL(m_pXMLDom->createElement(bstr1,&pEventElement),"create <Event> ");
	HRCALL(pEventElement->get_attributes(&pAttMap), "get_attributes: ");

	for (j = 0; j < eRADAttMax; j++)
	{
		var1 = pEvent->values[j];
		HRCALL(m_pXMLDom->createAttribute(atts[j], &pAttNode), "create attribute");
		HRCALL(pAttNode->put_nodeValue(var1), "node value");
		HRCALL(pAttMap->setNamedItem(pAttNode, &pIXMLDOMNode), "set named item");
		if (pIXMLDOMNode)
			pIXMLDOMNode->Release();
	}

clean: 
	if (pAttMap)
		pAttMap->Release();
	if (pAttNode)
		pAttNode->Release();

	return pEventElement;
}
Ejemplo n.º 5
0
///////////////////////////////////////////////////////
// RADEventsXML::XMLToEvent
//
// Populates a RADEvent object with string and typed values
// from the XML Event node attributes. The RADEvent class declares
// the string-to-type conversion operations, per field. The XML node
// attribute values are placed on the RADEvent as strings, without
// modification from the XML.
//
// Input:
//	pEvent	- the RADEvent instance
//
///////////////////////////////////////////////////////
RADEvent* RADEventsXML::XMLToEvent(IXMLDOMNode* pEvent)
{
	HRESULT hr;
	RADEvent* p = NULL;

	IXMLDOMNode *pAtt=NULL;
	IXMLDOMNamedNodeMap* pat = NULL;
	long l;
	int al;

	HRCALL(pEvent->get_attributes(&pat), "get_attributes: ");
	HRCALL(pat->get_length(&l), "get_length: ");
	ASSERT(l <= (int)eRADAttMax);

	p = new RADEvent();
	for (al = 0; al < l; al++)
	{
		HRCALL(pat->getNamedItem(atts[al], &pAtt), "gni");
		if (pAtt)
		{
			VARIANT varValue;
			::VariantInit(&varValue);
			pAtt->get_nodeValue(&varValue);
			p->SetREValue((RADEventField)al, varValue.bstrVal);
			::VariantClear(&varValue);
			pAtt->Release();
		}
	}

clean: 
	if (pat)
		pat->Release();
	return p;
}
Ejemplo n.º 6
0
bool SettingsXML::SetAttr(IXMLDOMNode* apNode, const wchar_t* asName, const wchar_t* asValue)
{
	bool lbRc = false;
	HRESULT hr = S_OK;
	IXMLDOMNamedNodeMap* pAttrs = NULL;
	hr = apNode->get_attributes(&pAttrs);

	if (SUCCEEDED(hr) && pAttrs)
	{
		lbRc = SetAttr(apNode, pAttrs, asName, asValue);
		pAttrs->Release(); pAttrs = NULL;
	}

	return lbRc;
}
Ejemplo n.º 7
0
BSTR SettingsXML::GetAttr(IXMLDOMNode* apNode, const wchar_t* asName)
{
	HRESULT hr = S_OK;
	BSTR bsValue = NULL;
	IXMLDOMNamedNodeMap* pAttrs = NULL;
	hr = apNode->get_attributes(&pAttrs);

	if (SUCCEEDED(hr) && pAttrs)
	{
		bsValue = GetAttr(apNode, pAttrs, asName);
		pAttrs->Release(); pAttrs = NULL;
	}

	return bsValue;
}
Ejemplo n.º 8
0
//--------------------------------------------------------------------------------------
BOOL ConfGetNodeAttributeW(IXMLDOMNode *pIDOMNode, PWSTR name, PWSTR *value)
{
    BOOL bRet = FALSE;
    IXMLDOMNamedNodeMap *pIXMLDOMNamedNodeMap = NULL;

    // query attributes map
    HRESULT hr = pIDOMNode->get_attributes(&pIXMLDOMNamedNodeMap);
    if (SUCCEEDED(hr) && pIXMLDOMNamedNodeMap)
    {
        IXMLDOMNode *pIDOMAttrNode = NULL;

        // query attribute node
        hr = pIXMLDOMNamedNodeMap->getNamedItem(name, &pIDOMAttrNode);
        if (SUCCEEDED(hr) && pIDOMAttrNode)
        {
            VARIANT varValue;
            hr = pIDOMAttrNode->get_nodeValue(&varValue);
            if (FAILED(hr))
            {
                DbgMsg(__FILE__, __LINE__, "pIDOMAttrNode->get_nodeValue() ERROR 0x%.8x\n", hr);
                goto free;
            }

            BSTR val = _bstr_t(varValue);
            DWORD Len = (wcslen((PWSTR)val) + 1) * sizeof(WCHAR);
            if (*value = (PWSTR)M_ALLOC(Len))
            {
                ZeroMemory(*value, Len);
                wcscpy(*value, (PWSTR)val);
                bRet = TRUE;
            }
            else
            {
                DbgMsg(__FILE__, __LINE__, "M_ALLOC() ERROR %d\n", GetLastError());
            }
free:
            pIDOMAttrNode->Release();
            pIDOMAttrNode = NULL;
        }

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

    return bRet;
}
Ejemplo n.º 9
0
/*
	Function name	: CXML::CreateAttributeNode
	Description	    : 
	Return type		: bool 
	Argument        : IXMLDOMNode **pParentNode
	Argument        : CString csAttribute
	Argument        : CString csValue
	Tested			: Ok
*/
bool CXML::CreateAttributeNode(IXMLDOMNode **pParentNode,CString csAttribute,CString csValue)
{
	IXMLDOMNode * pNode = NULL;
	if(csAttribute.IsEmpty())
		return false;

	if(!(*pParentNode))
		return false;

	_variant_t vtNodeType((long)NODE_ATTRIBUTE);

	_bstr_t bstrName(csAttribute);
	_bstr_t bstrNameSpace("");

	m_hr = m_pXMLDoc->createNode(vtNodeType,bstrName,bstrNameSpace,&pNode);
	if(!SUCCEEDED(m_hr))
		return false;

	IXMLDOMNamedNodeMap * pAttributes = NULL;
	m_hr = (*pParentNode)->get_attributes(&pAttributes);
	
	if(!SUCCEEDED(m_hr) || !pAttributes)
	{
		pNode->Release();
		return false;
	}

	IXMLDOMNode *pNewNode = NULL;
	m_hr = pAttributes->setNamedItem(pNode,&pNewNode);

	pNode->Release();
	pAttributes->Release();
	if(!SUCCEEDED(m_hr) || !pNewNode)
		return false;

	
	_variant_t vtValue(csValue);
	m_hr =	pNewNode->put_nodeValue(vtValue);

	pNewNode->Release();
	if(!SUCCEEDED(m_hr) || !pNewNode)
		return false;

	return true;
}
Ejemplo n.º 10
0
/******************************************************************************
Function Name  :  vRetrieveConditionSignalValue
Input(s)       :  IXMLDOMNode* pIDOMSChildSignal
                  CSignalCondition& ouSignalCondition
Output         :  void
Functionality  :  Retrieves the Signal Info from the pIDOMSChildSignal
Member of      :  CVerify_MessageEntity
Friend of      :  -
Author(s)      :  Venkatanarayana Makam
Date Created   :  06/04/2011
Modifications  :
******************************************************************************/
void CVerify_MessageEntity::vRetrieveConditionSignalValue(IXMLDOMNode* pIDOMSChildSignal, CSignalCondition& ouSignalCondition)
{
    CComBSTR bstrNodeName = L"name";
    CComVariant NodeValue;
    CString omstrTemp;
    IXMLDOMNamedNodeMap* pIDOMAttributes;
    IXMLDOMNode* pIDOMChildNode;

    pIDOMSChildSignal->get_attributes(&pIDOMAttributes);
    pIDOMAttributes->getNamedItem(bstrNodeName, &pIDOMChildNode);
    pIDOMChildNode->get_nodeTypedValue(&NodeValue);
    ouSignalCondition.m_omSigName = strCopyBSTRToCString(NodeValue);

    pIDOMChildNode->Release();
    pIDOMAttributes->Release();

    pIDOMSChildSignal->get_nodeTypedValue(&NodeValue);
    ouSignalCondition.m_omCondition = strCopyBSTRToCString(NodeValue);
    ouSignalCondition.m_omCondition.Remove('\"');
}
Ejemplo n.º 11
0
bool CXML::HasAttributes()
{
	if(!m_pICurrentNode)
		return false;

	IXMLDOMNamedNodeMap * pAttributeMap = 0;

	m_hr = m_pICurrentNode->get_attributes(&pAttributeMap);
	if (!SUCCEEDED(m_hr))
			return false;

	long nCount = 0;
	m_hr = pAttributeMap->get_length(&nCount);

	pAttributeMap->Release();

	if (!SUCCEEDED(m_hr))
			return false;

	return nCount != 0;
}
void lvDCOMInterface::getParams(std::map<std::string,std::string>& res)
{
	res.clear();
	char control_name_xpath[MAX_PATH_LEN];
	_snprintf(control_name_xpath, sizeof(control_name_xpath), "/lvinput/section[@name='%s']/vi/param", m_configSection.c_str());
	IXMLDOMNodeList* pXMLDomNodeList = NULL;
	HRESULT hr = m_pxmldom->selectNodes(_bstr_t(control_name_xpath), &pXMLDomNodeList);
	if (FAILED(hr) || pXMLDomNodeList == NULL)
	{
		return;
	}
	IXMLDOMNode *pNode, *pAttrNode1, *pAttrNode2;
	long n = 0;
	pXMLDomNodeList->get_length(&n);
	for(long i=0; i<n; ++i)
	{
		pNode = NULL;
		hr = pXMLDomNodeList->get_item(i, &pNode);
		if (SUCCEEDED(hr) && pNode != NULL)
		{
			IXMLDOMNamedNodeMap *attributeMap = NULL;
			pAttrNode1 = pAttrNode2 = NULL;
			pNode->get_attributes(&attributeMap);
			hr = attributeMap->getNamedItem(_bstr_t("name"), &pAttrNode1);
			hr = attributeMap->getNamedItem(_bstr_t("type"), &pAttrNode2);
			BSTR bstrValue1 = NULL, bstrValue2 = NULL;
			hr=pAttrNode1->get_text(&bstrValue1);
			hr=pAttrNode2->get_text(&bstrValue2);
			res[std::string(COLE2CT(bstrValue1))] = COLE2CT(bstrValue2);
			SysFreeString(bstrValue1);
			SysFreeString(bstrValue2);
			pAttrNode1->Release();
			pAttrNode2->Release();
			attributeMap->Release();
			pNode->Release();
		}
	}	
	pXMLDomNodeList->Release();
}
Ejemplo n.º 13
0
//void SettingsXML::Save(const wchar_t *regName, const wchar_t *value)
//{
//	if (!value) value = L"";  // сюда мог придти и NULL
//
//	Save(regName, (LPCBYTE)value, REG_SZ, (_tcslen(value)+1)*sizeof(wchar_t));
//}
void SettingsXML::Save(const wchar_t *regName, LPCBYTE value, DWORD nType, DWORD nSize)
{
	HRESULT hr = S_OK;
	IXMLDOMNamedNodeMap* pAttrs = NULL;
	IXMLDOMNodeList* pList = NULL;
	IXMLDOMAttribute *pIXMLDOMAttribute = NULL;
	IXMLDOMNode *pNode = NULL;
	IXMLDOMNode* pChild = NULL;
	IXMLDOMNode *pNodeRmv = NULL;
	BSTR bsValue = NULL;
	BSTR bsType = NULL;
	bool bNeedSetType = false;
	// nType:
	// REG_DWORD:    сохранение числа в 16-ричном или 10-чном формате, в зависимости от того, что сейчас указано в xml ("dword"/"ulong"/"long")
	// REG_BINARY:   строго в hex (FF,FF,...)
	// REG_SZ:       ASCIIZ строка, можно проконтролировать, чтобы nSize/2 не был меньше длины строки
	// REG_MULTI_SZ: ASCIIZZ. При формировании <list...> нужно убедиться, что мы не вылезли за пределы nSize
	pChild = FindItem(mp_Key, L"value", regName, true); // создать, если его еще нету

	if (!pChild)
		goto wrap;

	hr = pChild->get_attributes(&pAttrs);

	if (FAILED(hr) || !pAttrs)
		goto wrap;

	bsType = GetAttr(pChild, pAttrs, L"type");

	switch (nType)
	{
		case REG_DWORD:
		{
			wchar_t szValue[32];

			if (bsType && (bsType[0] == L'u' || bsType[0] == L'U'))
			{
				_wsprintf(szValue, SKIPLEN(countof(szValue)) L"%u", *(LPDWORD)value);
			}
			else if (bsType && (bsType[0] == L'l' || bsType[0] == L'L'))
			{
				_wsprintf(szValue, SKIPLEN(countof(szValue)) L"%i", *(int*)value);
			}
			else
			{
				_wsprintf(szValue, SKIPLEN(countof(szValue)) L"%08x", *(LPDWORD)value);

				if (bsType) ::SysFreeString(bsType);

				// нужно добавить/установить тип
				bsType = ::SysAllocString(L"dword"); bNeedSetType = true;
			}

			bsValue = ::SysAllocString(szValue);
		} break;
		case REG_BINARY:
		{
			if (nSize == 1 && bsType && (bsType[0] == L'u' || bsType[0] == L'U'))
			{
				wchar_t szValue[4];
				BYTE bt = *value;
				_wsprintf(szValue, SKIPLEN(countof(szValue)) L"%u", (DWORD)bt);
				bsValue = ::SysAllocString(szValue);
			}
			else if (nSize == 1 && bsType && (bsType[0] == L'l' || bsType[0] == L'L'))
			{
				wchar_t szValue[4];
				char bt = *value;
				_wsprintf(szValue, SKIPLEN(countof(szValue)) L"%i", (int)bt);
				bsValue = ::SysAllocString(szValue);
			}
			else
			{
				DWORD nLen = nSize*2 + (nSize-1); // по 2 символа на байт + ',' между ними
				bsValue = ::SysAllocStringLen(NULL, nLen);
				nLen ++; // Чтобы далее не добавлять WCHAR на '\0'
				wchar_t* psz = (wchar_t*)bsValue;
				LPCBYTE  ptr = value;

				while (nSize)
				{
					_wsprintf(psz, SKIPLEN(nLen-(psz-bsValue)) L"%02x", (DWORD)*ptr);
					ptr++; nSize--; psz+=2;

					if (nSize)
						*(psz++) = L',';
				}

				if (bsType && lstrcmp(bsType, L"hex"))
				{
					// Допустим только "hex"
					::SysFreeString(bsType); bsType = NULL;
				}

				if (!bsType)
				{
					// нужно добавить/установить тип
					bsType = ::SysAllocString(L"hex"); bNeedSetType = true;
				}
			}
		} break;
		case REG_SZ:
		{
			wchar_t* psz = (wchar_t*)value;
			bsValue = ::SysAllocString(psz);

			if (bsType && lstrcmp(bsType, L"string"))
			{
				// Допустим только "string"
				::SysFreeString(bsType); bsType = NULL;
			}

			if (!bsType)
			{
				// нужно добавить/установить тип
				bsType = ::SysAllocString(L"string"); bNeedSetType = true;
			}
		} break;
		case REG_MULTI_SZ:
		{
			if (bsType && lstrcmp(bsType, L"multi"))
			{
				// Допустим только "multi"
				::SysFreeString(bsType); bsType = NULL;
			}

			if (!bsType)
			{
				// нужно добавить/установить тип
				bsType = ::SysAllocString(L"multi"); bNeedSetType = true;
			}
		} break;
		default:
			goto wrap; // не поддерживается
	}

	if (bNeedSetType)
	{
		_ASSERTE(bsType!=NULL);
		SetAttr(pChild, pAttrs, L"type", bsType);
		::SysFreeString(bsType); bsType = NULL;
	}

	// Теперь собственно значение
	if (nType != REG_MULTI_SZ)
	{
		_ASSERTE(bsValue != NULL);
		SetAttr(pChild, pAttrs, L"data", bsValue);
		::SysFreeString(bsValue); bsValue = NULL;
	}
	else     // Тут нужно формировать список элементов <list>
	{
		// Если ранее был параметр "data" - удалить его из списка атрибутов
		hr = pAttrs->getNamedItem(L"data", &pNode);
		if (SUCCEEDED(hr) && pNode)
		{
			hr = pChild->removeChild(pNode, &pNodeRmv);
			pNode->Release(); pNode = NULL;
			SetDataChanged();

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

		long nAllLen = nSize/2; // длина в wchar_t
		wchar_t* psz = (wchar_t*)value;
		SetMultiLine(pChild, psz, nAllLen);
	}

	mb_Modified = true;
wrap:

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

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

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

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

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

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

	if (bsType) { ::SysFreeString(bsType); bsType = NULL; }
}
/**Read the XML config file. Currently contains keyboard choices.*/
void read_config_file()
{
	TrainerConfig *result = new TrainerConfig();

	CoInitialize(NULL);

	//read XML
	MSXML2::IXMLDOMDocumentPtr spXMLDoc;
	spXMLDoc.CreateInstance(__uuidof(MSXML2::DOMDocument60));
	if (!spXMLDoc->load("ent-config.xml"))
	{
		write_text_to_log_file("No config found, using defaults");
		config = result; //the default config
	}

	IXMLDOMNodeListPtr nodes = spXMLDoc->selectNodes(L"//ent-config/keys/key");

	long length;
	nodes->get_length(&length);
	for (int i = 0; i < length; i++)
	{
		IXMLDOMNode *node;
		nodes->get_item(i, &node);
		IXMLDOMNamedNodeMap *attribs;
		node->get_attributes(&attribs);

		long length_attribs;
		attribs->get_length(&length_attribs);

		char *attrib_key_func = NULL;
		char *attrib_key_value = NULL;

		for (long j = 0; j < length_attribs; j++)
		{
			IXMLDOMNode *attribNode;
			attribs->get_item(j, &attribNode);
			attribNode->get_nodeName(&bstr);
			if (wcscmp(bstr, L"function") == 0)
			{
				VARIANT var;
				VariantInit(&var);
				attribNode->get_nodeValue(&var);
				attrib_key_func = _com_util::ConvertBSTRToString(V_BSTR(&var));
			}
			else if (wcscmp(bstr, L"value") == 0)
			{
				VARIANT var;
				VariantInit(&var);
				attribNode->get_nodeValue(&var);
				attrib_key_value = _com_util::ConvertBSTRToString(V_BSTR(&var));
			}
			SysFreeString(bstr);
			attribNode->Release();
		}
		
		if (attrib_key_func != NULL && attrib_key_value != NULL)
		{
			result->get_key_config()->set_key(attrib_key_func, attrib_key_value);
		}
		
		delete attrib_key_func;
		delete attrib_key_value;

		attribs->Release();
		node->Release();
	}

	//nodes->Release(); //don't do this, it crashes on exit
	spXMLDoc.Release();
	CoUninitialize();
	
	config = result;
}
Ejemplo n.º 15
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.º 16
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;
}
void CStrokeRecognition::DecodePointFromXML(std::vector<POINT> &rgPoints, BSTR strXML)
{
	IXMLDOMDocument*		pDoc;
	IXMLDOMNodeList*		pNodeList;
	IXMLDOMNode*			pNode;
	IXMLDOMNode*			pInputNode;
	IXMLDOMNode*			pAttrNode;
	IXMLDOMNamedNodeMap*	pNodeMap;
	VARIANT_BOOL			bLoaded;
	VARIANT					value;
	BSTR					nodeName;
	POINT					pt;
	long					n;

	if (SUCCEEDED(CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (LPVOID*)&pDoc)))
	{
		pDoc->put_async(VARIANT_FALSE);
		pDoc->loadXML(strXML, &bLoaded);

		if (bLoaded == VARIANT_TRUE)
		{
			if (SUCCEEDED(pDoc->get_childNodes(&pNodeList)))
			{
				pInputNode = NULL;

				pNodeList->get_length(&n);

				for (int i = 0; i < n; i++)
				{
					if (SUCCEEDED(pNodeList->get_item(i, &pNode)))
					{
						nodeName = NULL;
						if (SUCCEEDED(pNode->get_nodeName(&nodeName)))
						{
							if (CComBSTR(nodeName) == L"input")
							{
								pInputNode = pNode;
								pInputNode->AddRef();
								break;
							}
							SysFreeString(nodeName);
						}
						pNode->Release();
					}
				}

				pNodeList->Release();

				if (pInputNode != NULL)
				{
					if (SUCCEEDED(pInputNode->get_childNodes(&pNodeList)))
					{
						pNodeList->get_length(&n);

						for (int i = 0; i < n; i++)
						{
							if (SUCCEEDED(pNodeList->get_item(i, &pNode)))
							{
								pt.x = 0;
								pt.y = 0;

								if (SUCCEEDED(pNode->get_attributes(&pNodeMap)))
								{
									if (SUCCEEDED(pNodeMap->getNamedItem(L"x", &pAttrNode)))
									{
										pAttrNode->get_nodeValue(&value);
										pt.x = _wtoi(value.bstrVal);
										pAttrNode->Release();
									}

									if (SUCCEEDED(pNodeMap->getNamedItem(L"y", &pAttrNode)))
									{
										pAttrNode->get_nodeValue(&value);
										pt.y = _wtoi(value.bstrVal);
										pAttrNode->Release();
									}

									pNodeMap->Release();
								}

								rgPoints.push_back(pt);

								pNode->Release();
							}
						}

						pNodeList->Release();
					}

					pInputNode->Release();
				}
			}
		}

		pDoc->Release();
	}
}
Ejemplo n.º 18
0
bool SettingsXML::Load(const wchar_t *regName, LPBYTE value, DWORD nSize)
{
	bool lbRc = false;
	HRESULT hr = S_OK;
	IXMLDOMNode* pChild = NULL;
	IXMLDOMNamedNodeMap* pAttrs = NULL;
	IXMLDOMAttribute *pIXMLDOMAttribute = NULL;
	IXMLDOMNode *pNode = NULL;
	BSTR bsType = NULL;
	BSTR bsData = NULL;

	if (!value || !nSize)
		return false;

	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)
	{
		bsData = GetAttr(pChild, pAttrs, L"data");
	}

	if (SUCCEEDED(hr) && bsData)
	{
		if (!lstrcmpi(bsType, L"string"))
		{
			#ifdef _DEBUG
			DWORD nLen = _tcslen(bsData) + 1;
			#endif
			DWORD nMaxLen = nSize / 2;
			lstrcpyn((wchar_t*)value, bsData, nMaxLen);
			lbRc = true;
		}
		else if (!lstrcmpi(bsType, L"ulong"))
		{
			wchar_t* pszEnd = NULL;
			DWORD lVal = wcstoul(bsData, &pszEnd, 10);

			if (nSize > 4) nSize = 4;

			if (pszEnd && pszEnd != bsData)
			{
				memmove(value, &lVal, nSize);
				lbRc = true;
			}
		}
		else if (!lstrcmpi(bsType, L"long"))
		{
			wchar_t* pszEnd = NULL;
			int lVal = wcstol(bsData, &pszEnd, 10);

			if (nSize > 4) nSize = 4;

			if (pszEnd && pszEnd != bsData)
			{
				memmove(value, &lVal, nSize);
				lbRc = true;
			}
		}
		else if (!lstrcmpi(bsType, L"dword"))
		{
			wchar_t* pszEnd = NULL;
			DWORD lVal = wcstoul(bsData, &pszEnd, 16);

			if (nSize > 4) nSize = 4;

			if (pszEnd && pszEnd != bsData)
			{
				memmove(value, &lVal, nSize);
				lbRc = true;
			}
		}
		else if (!lstrcmpi(bsType, L"hex"))
		{
			wchar_t* pszCur = bsData;
			wchar_t* pszEnd = NULL;
			LPBYTE pCur = value;
			wchar_t cHex;
			DWORD lVal = 0;
			lbRc = true;

			while (*pszCur && nSize)
			{
				lVal = 0;
				cHex = *(pszCur++);

				if (cHex >= L'0' && cHex <= L'9')
				{
					lVal = cHex - L'0';
				}
				else if (cHex >= L'a' && cHex <= L'f')
				{
					lVal = cHex - L'a' + 10;
				}
				else if (cHex >= L'A' && cHex <= L'F')
				{
					lVal = cHex - L'A' + 10;
				}
				else
				{
					lbRc = false; break;
				}

				cHex = *(pszCur++);

				if (cHex && cHex != L',')
				{
					lVal = lVal << 4;

					if (cHex >= L'0' && cHex <= L'9')
					{
						lVal |= cHex - L'0';
					}
					else if (cHex >= L'a' && cHex <= L'f')
					{
						lVal |= cHex - L'a' + 10;
					}
					else if (cHex >= L'A' && cHex <= L'F')
					{
						lVal |= cHex - L'A' + 10;
					}
					else
					{
						lbRc = false; break;
					}

					cHex = *(pszCur++);
				}

				*pCur = (BYTE)lVal;
				pCur++; nSize--;

				if (cHex != L',')
				{
					break;
				}
			}

			while (nSize--)  // очистить хвост
				*(pCur++) = 0;
		}
	}

	// Остальные типы (строки) - не интересуют

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

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

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

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

	return lbRc;
}
STDMETHODIMP CStrokeRecognition::put_RecognitionParam(BSTR newVal)
{
	double		Segment_Error_Threshold;
	double		Arc_Error_Threshold;
	double		Arc_Min_Length;
	double		Arc_Min_Curve;
	double		Stroke_Min_Length;
	double		Min_Turning_Angle;
	double		Segmentation_Penalty;
	VARIANT		value;
	BSTR		nodeName;
	long		n;

	IXMLDOMDocument*		pDoc;
	IXMLDOMNodeList*		pNodeList;
	IXMLDOMNode*			pNode;
	IXMLDOMNode*			pParamNode;
	IXMLDOMNode*			pAttrNode;
	IXMLDOMNamedNodeMap*	pNodeMap;
	VARIANT_BOOL			bLoaded;

	GetFittingParam(Segment_Error_Threshold, Arc_Error_Threshold, Arc_Min_Length, Arc_Min_Curve, Stroke_Min_Length, Min_Turning_Angle, Segmentation_Penalty);

	if (SUCCEEDED(CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (LPVOID*)&pDoc)))
	{
		pDoc->put_async(VARIANT_FALSE);
		pDoc->loadXML(newVal, &bLoaded);

		if (bLoaded == VARIANT_TRUE)
		{
			if (SUCCEEDED(pDoc->get_childNodes(&pNodeList)))
			{
				pParamNode = NULL;

				pNodeList->get_length(&n);

				for (int i = 0; i < n; i++)
				{
					if (SUCCEEDED(pNodeList->get_item(i, &pNode)))
					{
						nodeName = NULL;
						if (SUCCEEDED(pNode->get_nodeName(&nodeName)))
						{
							if (CComBSTR(nodeName) == L"param")
							{
								pParamNode = pNode;
								pParamNode->AddRef();
								break;
							}
							SysFreeString(nodeName);
						}
						pNode->Release();
					}
				}

				pNodeList->Release();

				if (pParamNode != NULL)
				{
					if (SUCCEEDED(pParamNode->get_attributes(&pNodeMap)))
					{
						if (SUCCEEDED(pNodeMap->getNamedItem(L"Segment_Error_Threshold", &pAttrNode)))
						{
							pAttrNode->get_nodeValue(&value);
							Segment_Error_Threshold = _wtof(value.bstrVal);
							pAttrNode->Release();
						}
						if (SUCCEEDED(pNodeMap->getNamedItem(L"Arc_Error_Threshold", &pAttrNode)))
						{
							pAttrNode->get_nodeValue(&value);
							Arc_Error_Threshold = _wtof(value.bstrVal);
							pAttrNode->Release();
						}
						if (SUCCEEDED(pNodeMap->getNamedItem(L"Arc_Min_Length", &pAttrNode)))
						{
							pAttrNode->get_nodeValue(&value);
							Arc_Min_Length = _wtof(value.bstrVal);
							pAttrNode->Release();
						}
						if (SUCCEEDED(pNodeMap->getNamedItem(L"Arc_Min_Curve", &pAttrNode)))
						{
							pAttrNode->get_nodeValue(&value);
							Arc_Min_Curve = _wtof(value.bstrVal);
							pAttrNode->Release();
						}
						if (SUCCEEDED(pNodeMap->getNamedItem(L"Stroke_Min_Length", &pAttrNode)))
						{
							pAttrNode->get_nodeValue(&value);
							Stroke_Min_Length = _wtof(value.bstrVal);
							pAttrNode->Release();
						}
						if (SUCCEEDED(pNodeMap->getNamedItem(L"Min_Turning_Angle", &pAttrNode)))
						{
							pAttrNode->get_nodeValue(&value);
							Min_Turning_Angle = _wtof(value.bstrVal);
							pAttrNode->Release();
						}
						if (SUCCEEDED(pNodeMap->getNamedItem(L"Segmentation_Penalty", &pAttrNode)))
						{
							pAttrNode->get_nodeValue(&value);
							Segmentation_Penalty = _wtof(value.bstrVal);
							pAttrNode->Release();
						}

						pNodeMap->Release();
					}

					pParamNode->Release();
				}
			}
		}

		pDoc->Release();
	}

	SetFittingParam(Segment_Error_Threshold, Arc_Error_Threshold, Arc_Min_Length, Arc_Min_Curve, Stroke_Min_Length, Min_Turning_Angle, Segmentation_Penalty);

	return S_OK;
}
Ejemplo n.º 20
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;
}