// 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; }