// XmlUtils.cpp: implementation of the CXmlUtils class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "KBEditors.h"
#include "XmlUtils.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
MSXML::IXMLDOMNode * CXmlUtils::AddNode(MSXML::IXMLDOMDocument* pDoc, MSXML::IXMLDOMNode * Parent, CString tagName, CString text)
{
HRESULT hr = S_OK;
MSXML::IXMLDOMNode * pNode;
//Convert the tagname, text to unicode
BSTR bTagName;
BSTR bText;
bTagName = tagName.AllocSysString();
if(!text.IsEmpty())
bText = text.AllocSysString();
//Put the type to be an element
VARIANT vtype;
vtype.vt = VT_I4;
V_I4(&vtype) = (int)MSXML::NODE_ELEMENT;
//create the node
CHECKHR(pDoc->createNode(vtype, bTagName , NULL, &pNode));
SysFreeString(bTagName);
CHECKHR(Parent->appendChild(pNode, NULL));
if (!text.IsEmpty()){
CHECKHR(pNode->put_text(bText));
SysFreeString(bText);
}
return pNode;
CleanUp:
SysFreeString(bTagName);
SysFreeString(bText);
SAFERELEASE(pNode);
return NULL;
}
MSXML::IXMLDOMDocument* CXmlUtils::CreateDoc()
{
HRESULT hr = S_OK;
MSXML::IXMLDOMDocument *pDoc = NULL;
CHECKHR(CoCreateInstance(MSXML::CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER,
MSXML::IID_IXMLDOMDocument, (void**)&pDoc));
return pDoc;
CleanUp:
SAFERELEASE(pDoc);
return NULL;
}
CString CXmlUtils::GetXML(MSXML::IXMLDOMNode *pNode)
{
BSTR bXmlString;
CString xml;
HRESULT hr = S_OK;
CHECKHR(pNode->get_xml(&bXmlString));
(bXmlString);
xml = bXmlString;
return xml;
CleanUp:
return "";
}
BOOL CXmlUtils::loadXMLStr(MSXML::IXMLDOMDocument *pDoc, BSTR xmlString, char **Error)
{
HRESULT hr = S_OK;
VARIANT_BOOL isSuccessful;
CHECKHR(pDoc->loadXML(xmlString, &isSuccessful));
CHECKHR(CheckLoad(pDoc, Error));
return isSuccessful;
CleanUp:
return FALSE;
}
BOOL CXmlUtils::loadXMLCStr(MSXML::IXMLDOMDocument *pDoc, CString xmlString, char **Error)
{
HRESULT hr = S_OK;
VARIANT_BOOL isSuccessful;
BSTR bstr = xmlString.AllocSysString();
CHECKHR(pDoc->loadXML(bstr, &isSuccessful));
CHECKHR(CheckLoad(pDoc, Error));
SysFreeString(bstr);
return isSuccessful;
CleanUp:
return FALSE;
}
////////////////////////////////////////////////////////////////////////////
// Helper function: Check load results
////////////////////////////////////////////////////////////////////////////
HRESULT CXmlUtils::CheckLoad(MSXML::IXMLDOMDocument* pDoc, char **Error)
{
// And since we don't have the VARIANT_BOOL from load we
// need to check the parse Error errorCode property to see
// if everything went ok.
MSXML::IXMLDOMParseError *pXMLError = NULL;
LONG errorCode = E_FAIL;
HRESULT hr;
CHECKHR(pDoc->get_parseError(&pXMLError));
CHECKHR(pXMLError->get_errorCode(&errorCode));
if (errorCode != 0)
{
hr = ReportError(pXMLError, Error);
goto CleanUp;
}
else
{
return S_OK;
}
CleanUp:
SAFERELEASE(pXMLError);
return errorCode;
}
HRESULT CXmlUtils::ReportError(MSXML::IXMLDOMParseError *pXMLError, char ** Error)
{
long line, linePos;
LONG errorCode;
BSTR pBReason;
HRESULT hr;
CHECKHR(pXMLError->get_line(&line));
CHECKHR(pXMLError->get_linepos(&linePos));
CHECKHR(pXMLError->get_errorCode(&errorCode));
CHECKHR(pXMLError->get_reason(&pBReason));
if (line > 0) {
wsprintf(*Error,
" \"%S\" %d %d ", pBReason, line, linePos);
}
else {
wsprintf(*Error, " \"%S\" ", pBReason);
}
CleanUp:
SysFreeString(pBReason);
return E_FAIL;
}
////////////////////////////////////////////////////////////////////////////
// Function: Save document out to specified local file.
////////////////////////////////////////////////////////////////////////////
BOOL CXmlUtils :: SaveDocument(MSXML::IXMLDOMDocument *pDoc, CString fName)
{
HRESULT hr = S_OK;
VARIANT vName;
BSTR bFName;
bFName=fName.AllocSysString();
vName.vt = VT_BSTR;
V_BSTR(&vName) = bFName;
CHECKHR(pDoc->save(vName));
SysFreeString(bFName);
return TRUE;
CleanUp:
SysFreeString(bFName);
return FALSE;
}
CString CXmlUtils :: ftoa(float source)
{
int decimal, sign;
char *buffer;
CString result;
buffer = _fcvt( source, 2, &decimal, &sign );
result.Format("%s%s",sign==1?"-":"" ,buffer);
return result;
}
CString CXmlUtils :: itoa(int i)
{
char buffer[20];
_itoa( i, buffer, 10 );
CString result;
result.Format("%s",buffer);
return result;
}
CString CXmlUtils :: GetNodeTextByIndex(MSXML::IXMLDOMNodeList *pNodeList, int i) {
BSTR bText;
CString x;
MSXML::IXMLDOMNode *pChildNode;
HRESULT hr = S_OK;
CHECKHR(pNodeList->get_item(i,&pChildNode));
CHECKHR(pChildNode->get_text(&bText));
x = bText;
SysFreeString(bText);
SAFERELEASE(pChildNode);
return x;
CleanUp:
SysFreeString(bText);
SAFERELEASE(pChildNode);
x="";
return x;
}
MSXML::IXMLDOMNodeList* CXmlUtils :: GetNodeList(MSXML::IXMLDOMNode *pParent, CString str){
HRESULT hr = S_OK;
CString pattern;
BSTR bTagName;
MSXML::IXMLDOMNodeList* nodeList;
pattern = str;
bTagName = pattern.AllocSysString();
CHECKHR(pParent->selectNodes(bTagName,&nodeList));
SysFreeString(bTagName);
return nodeList;
CleanUp:
SAFERELEASE(nodeList);
SysFreeString(bTagName);
return NULL;
}
CString CXmlUtils :: GetNodeTextByName(MSXML::IXMLDOMNode *pParent, CString str){
BSTR bText, bPattern;
CString x;
MSXML::IXMLDOMNode *pChildNode;
HRESULT hr = S_OK;
bPattern = str.AllocSysString();
CHECKHR(pParent->selectSingleNode(bPattern,&pChildNode));
SysFreeString(bPattern);
CHECKHR(pChildNode->get_text(&bText));
x = bText;
SysFreeString(bText);
SAFERELEASE(pChildNode);
return x;
CleanUp:
SysFreeString(bText);
SysFreeString(bPattern);
SAFERELEASE(pChildNode);
x="";
return x;
}
MSXML::IXMLDOMNode * CXmlUtils :: GetNodeByName(MSXML::IXMLDOMNode *pParent, CString str){
BSTR bPattern;
MSXML::IXMLDOMNode *pChildNode;
HRESULT hr = S_OK;
bPattern = str.AllocSysString();
CHECKHR(pParent->selectSingleNode(bPattern,&pChildNode));
SysFreeString(bPattern);
return pChildNode;
CleanUp:
SysFreeString(bPattern);
SAFERELEASE(pChildNode);
return NULL;
}
////////////////////////////////////////////////////////////////////////////
// Helper Function: Load an XML Document from the specified file or URL synchronously.
////////////////////////////////////////////////////////////////////////////
BOOL CXmlUtils :: LoadDocumentSync(MSXML::IXMLDOMDocument *pDoc, CString fName, char **Error)
{
MSXML::IXMLDOMParseError *pXMLError = NULL;
VARIANT vURL;
VARIANT_BOOL vb;
HRESULT hr;
BSTR pBURL;
pBURL = fName.AllocSysString();
CHECKHR(pDoc->put_async(VARIANT_FALSE));
// Load xml document from the given URL or file path
VariantInit(&vURL);
vURL.vt = VT_BSTR;
V_BSTR(&vURL) = pBURL;
CHECKHR(pDoc->load(vURL, &vb));
CHECKHR(CheckLoad(pDoc,Error));
SysFreeString(pBURL);
return TRUE;
CleanUp:
SysFreeString(pBURL);
SAFERELEASE(pXMLError);
return FALSE;
}
CString CXmlUtils::GetText(MSXML::IXMLDOMNode *pNode)
{
BSTR bText;
CString x;
HRESULT hr = S_OK;
CHECKHR(pNode->get_text(&bText));
x = bText;
SysFreeString(bText);
return x;
CleanUp:
SysFreeString(bText);
x="";
return x;
}