#include "stdafx.h" #include "XMLDOMFile.h" #include "XMLDOMNode.h" #include "XMLDOMNodes.h" #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif inline void TESTHR( HRESULT _hr ) { if ( FAILED( _hr) ) { throw(_hr); } } TCHAR* CXMLDOMFile::m_strFileName; MSXML2::IXMLDOMDocument2Ptr CXMLDOMFile::m_pXMLDOMDocument; CXMLDOMFile::CXMLDOMFile() { TESTHR( CoInitialize(NULL) ); m_pXMLDOMDocument = NULL ; //m_strFileName = NULL; } CXMLDOMFile:: ~CXMLDOMFile() { //MessageBox( NULL, TEXT("CXMLDOMFile_Deconstructor"), TEXT("Information"), MB_OK ); if( NULL != m_strFileName) { delete [] m_strFileName; m_strFileName = NULL; } if( NULL != m_pXMLDOMDocument ) { m_pXMLDOMDocument.Release(); } m_pXMLDOMDocument = NULL; CoUninitialize(); } bool CXMLDOMFile::IsFileExist( const TCHAR* strFileName ) { assert( NULL != strFileName ); if( NULL == strFileName ) { return false; } bool bExist = false; HANDLE hFile = NULL; try { hFile = CreateFile( strFileName, GENERIC_READ, FILE_SHARE_READ , NULL, OPEN_EXISTING, NULL, NULL ); if( hFile != INVALID_HANDLE_VALUE ) { CloseHandle( hFile ); hFile = NULL; bExist = true; } } catch ( ... ) { #ifdef _DEBUG MessageBox( NULL, TEXT("UnKnown error occured!"), TEXT("Error"), MB_OK|MB_ICONSTOP ); #endif return false; } return bExist; } bool CXMLDOMFile::Open( const TCHAR* strFileName ) { if( NULL == strFileName ) { return false; } //bool bOpenSuccess = false; m_strFileName = NULL; m_pXMLDOMDocument = NULL; using namespace MSXML2; //HRESULT hr ; try { //MSXML2::IXMLDOMDocument2Ptr pXMLDOMDocument = GetPtr(); // Zyu modify on 100727,支持64位 HRESULT hr =m_pXMLDOMDocument.CreateInstance( __uuidof( MSXML2::DOMDocument60 ) ); if ( FAILED( hr ) ) { #ifdef DEBUG TRACE1( "Failed to CreateInstance() .\nError:%s\n" , ( TCHAR* )m_pXMLDOMDocument->parseError->Getreason() ); #endif m_pXMLDOMDocument = NULL; return false; } m_pXMLDOMDocument->async = VARIANT_FALSE; if ( m_pXMLDOMDocument->load( strFileName ) != VARIANT_TRUE ) { #ifdef DEBUG TRACE1( "Failed load xml data from file.\nError:%s\n" , ( TCHAR* )m_pXMLDOMDocument->parseError->Getreason() ); CString strErr(_T("")); strErr.Format(_T("\nCXMLDOMFile::Open: Failed load xml data from file.\nError:%s\n"), (LPCSTR)m_pXMLDOMDocument->parseError->Getreason()); OutputDebugString( strErr ); #endif m_pXMLDOMDocument.Release(); m_pXMLDOMDocument = NULL; return false; } } catch ( ... ) { #ifdef _DEBUG MessageBox( NULL, TEXT("UnKnown error occured!"), TEXT("Error"), MB_OK|MB_ICONSTOP ); #endif if( NULL != m_pXMLDOMDocument ) { m_pXMLDOMDocument.Release(); m_pXMLDOMDocument = NULL; } return false; } m_strFileName = new TCHAR[ ( int )_tcslen( strFileName ) + 1 ]; if( NULL == m_strFileName ) { m_pXMLDOMDocument.Release(); return false; } _tcscpy( m_strFileName, strFileName ); return true; } bool CXMLDOMFile::CreateNewXMLDoc(const TCHAR* strFileName,const TCHAR* strProcessingInstruction ,const TCHAR*strRootNodeName,const NodeAttriButeAry&nodeInfoAry) { bool bResult = false; if( NULL == strFileName ) { return false; } m_strFileName = NULL; m_pXMLDOMDocument = NULL; using namespace MSXML2; MSXML2::IXMLDOMProcessingInstructionPtr pIXMLDOMProcessingInstruction=NULL; MSXML2::IXMLDOMNodePtr pIXMLDOMNode = NULL; MSXML2::IXMLDOMElementPtr pXMLDOMElement = NULL; HRESULT hr ; try { // Zyu modify on 100727,支持64位 hr =m_pXMLDOMDocument.CreateInstance( __uuidof( MSXML2::DOMDocument60 ) ); if ( FAILED( hr ) ) { #ifdef DEBUG TRACE1( "Failed to CreateInstance() .\nError:%s\n" , ( TCHAR* )m_pXMLDOMDocument->parseError->Getreason() ); #endif m_pXMLDOMDocument = NULL; return false; } //SUCCEEDED(hr) ? 0 : throw hr; if(m_pXMLDOMDocument) { pIXMLDOMProcessingInstruction = m_pXMLDOMDocument->createProcessingInstruction(_T("xml"), _bstr_t(strProcessingInstruction)); if(pIXMLDOMProcessingInstruction) { _variant_t vNullVal; vNullVal.vt = VT_NULL; m_pXMLDOMDocument->insertBefore(pIXMLDOMProcessingInstruction,vNullVal); _variant_t varNodeType((short)MSXML2::NODE_ELEMENT); pIXMLDOMNode=m_pXMLDOMDocument->createNode(varNodeType,_bstr_t(strRootNodeName),_T("")); pXMLDOMElement = static_cast< MSXML2::IXMLDOMElementPtr >(pIXMLDOMNode); int nLen = nodeInfoAry.GetLength(); int i=0; for (;isetAttribute( _bstr_t(nodeInfo.first), _variant_t((TCHAR*)(nodeInfo.second.GetBuffer(0)))); } if (pIXMLDOMNode!=NULL) { m_pXMLDOMDocument->appendChild(pIXMLDOMNode); pIXMLDOMNode->appendChild(m_pXMLDOMDocument->createTextNode("\n")); } if(SUCCEEDED(hr)) { bResult=TRUE; } hr = m_pXMLDOMDocument->save(_variant_t((TCHAR*)strFileName)); } } } catch(...) { if (pIXMLDOMNode) { pIXMLDOMNode.Release(); } if (pIXMLDOMProcessingInstruction) { pIXMLDOMProcessingInstruction.Release(); } if( NULL != m_pXMLDOMDocument ) { m_pXMLDOMDocument.Release(); m_pXMLDOMDocument = NULL; } return false; } m_strFileName = new TCHAR[ ( int )_tcslen( strFileName ) + 1 ]; if( NULL == m_strFileName ) { m_pXMLDOMDocument.Release(); return false; } _tcscpy( m_strFileName, strFileName ); return bResult; } bool CXMLDOMFile::Save( const TCHAR* strSaveAsFileName /* = NULL */) { //assert( NULL != m_pXMLDOMDocument ); if( NULL == m_pXMLDOMDocument ) { return false; } HRESULT hr; try { //xsl样式单 CString strMyStyle = _T("\n\n\n\n\n\n\n\n"); IXMLDOMDocument2Ptr pStyle=NULL; // Zyu modify on 100727,支持64位 hr = pStyle.CreateInstance(__uuidof( MSXML2::DOMDocument60 )); CString strStyle(strMyStyle); pStyle->loadXML(strStyle.AllocSysString()); IXMLDOMDocument2Ptr pNew=NULL; // Zyu modify on 100727,支持64位 hr = pNew.CreateInstance(__uuidof(MSXML2::DOMDocument60)); pNew->loadXML(m_pXMLDOMDocument->transformNode(pStyle)); CString strNew((BSTR)(pNew->xml)); strNew=CString("\n")+strNew; pNew.Release(); pNew = NULL; //pNew.CreateInstance(__uuidof(MSXML2::DOMDocument40)); //pNew->loadXML(strNew.AllocSysString()); if( NULL != m_pXMLDOMDocument ) { m_pXMLDOMDocument.Release(); } m_pXMLDOMDocument = NULL; // Zyu modify on 100727,支持64位 hr = m_pXMLDOMDocument.CreateInstance(__uuidof(MSXML2::DOMDocument60)); m_pXMLDOMDocument->loadXML(strNew.AllocSysString()); if( NULL == strSaveAsFileName ) // Save it to Original file name. { hr = m_pXMLDOMDocument->save( _variant_t ( ( TCHAR* ) m_strFileName ) ); } else // Save it to New name. { hr = m_pXMLDOMDocument->save( _variant_t( ( TCHAR* ) strSaveAsFileName ) ); } //pNew.Release(); //pNew = NULL; } catch ( ... ) { #ifdef _DEBUG MessageBox( NULL, TEXT("UnKnown error occured!"), TEXT("Error"), MB_OK|MB_ICONSTOP ); #endif return false; } return SUCCEEDED( hr ); } CXMLDOMNodePtr CXMLDOMFile::GetRoot( void ) { if( NULL == m_pXMLDOMDocument ) { RETURN_NULL; } MSXML2::IXMLDOMElementPtr pXMLDOMElement = NULL; HRESULT hr; try { hr = m_pXMLDOMDocument->get_documentElement( &pXMLDOMElement ); assert( SUCCEEDED( hr ) ); if( FAILED( hr ) ) { RETURN_NULL; } } catch ( ... ) { #ifdef _DEBUG MessageBox( NULL, TEXT("UnKnown error occured!"), TEXT("Error"), MB_OK|MB_ICONSTOP ); #endif if( NULL != pXMLDOMElement ) { pXMLDOMElement.Release(); pXMLDOMElement = NULL; } RETURN_NULL; } CXMLDOMNodePtr pXMLDOMNode( new CXMLDOMNode( pXMLDOMElement ) );// Must implementation for CXMLDOMNode( MSXML2::IXMLDOMNodePtr pXMLDOMNode ) // To avoid memory leaks, you must release a pointer to an IXMLDOMElement interface. if( NULL != pXMLDOMElement ) { pXMLDOMElement.Release(); pXMLDOMElement = NULL; } return pXMLDOMNode; } TCHAR* CXMLDOMFile::GetXMLFileName( void ) { if( NULL == m_strFileName ) { return NULL; } return m_strFileName; } CXMLDOMNodePtr CXMLDOMFile::SelectSingleNode( const TCHAR* szNodeXPath ) { //assert( NULL != m_pXMLDOMDocument ); if( NULL == m_pXMLDOMDocument ) { RETURN_NULL; } if( NULL == szNodeXPath ) { RETURN_NULL; } MSXML2::IXMLDOMNodePtr pXMLDOMNode = NULL; try { pXMLDOMNode = m_pXMLDOMDocument->selectSingleNode( _bstr_t ( szNodeXPath ) ); if( NULL == pXMLDOMNode ) { MSXML2::IXMLDOMNodeListPtr pList = m_pXMLDOMDocument->selectNodes(_bstr_t ( szNodeXPath )); if (NULL == pList) { //assert( false ); RETURN_NULL; } else { long length = pList->Getlength(); if (length>0) { pXMLDOMNode = pList->Getitem(0); } else { pList.Release(); pList = NULL; //assert( false ); RETURN_NULL; } } } } catch(...) { if( NULL != pXMLDOMNode ) { pXMLDOMNode.Release(); pXMLDOMNode = NULL; } //assert( false ); RETURN_NULL; } CXMLDOMNodePtr pRetXMLDOMNode ( new CXMLDOMNode( pXMLDOMNode ) ); if( NULL != pXMLDOMNode ) { pXMLDOMNode.Release(); pXMLDOMNode = NULL; } return pRetXMLDOMNode; } CXMLDOMNodePtr CXMLDOMFile::GetAssignNode(const TCHAR*szNodeName,const TCHAR*szNodeAttribute) { //assert( NULL != m_pXMLDOMDocument ); if( NULL == m_pXMLDOMDocument) { RETURN_NULL; } //assert( NULL != szNodeName); if( NULL == szNodeName) { RETURN_NULL; } CString strNode = szNodeName; if (strNode == _T("所有词条")) { strNode == _T("上华词库"); } CXMLDOMNodesPtr pXMLDOMNodesPtr = GetNodesByTagName(strNode); int nCount = pXMLDOMNodesPtr->GetCount(); CXMLDOMNodePtr pXMLDOMNodePtr(new CXMLDOMNode(NULL)); //MSXML2::IXMLDOMNodePtr pXMLDOMNode = NULL; if (nCount == 0) { RETURN_NULL; } else if(nCount == 1) { pXMLDOMNodePtr = pXMLDOMNodesPtr->GetItem(0); } else if(nCount>1) { CString strNodeAttribute = szNodeAttribute; int i=0; for(i =0 ;iGetItem(i); strNodeAttriName = pXMLDOMNodePtr->GetAttributeName(); strNodeAttriTem = pXMLDOMNodePtr->GetAttributeValue(strNodeAttriName); if (strNodeAttribute == strNodeAttriTem) { break; } } } return pXMLDOMNodePtr; } CXMLDOMNodesPtr CXMLDOMFile::GetNodesByTagName(const TCHAR*szNodeName) { //assert( NULL != m_pXMLDOMDocument ); if( NULL == m_pXMLDOMDocument) { RETURNLIST_NULL; } //assert( NULL != szNodeName); if( NULL == szNodeName) { RETURNLIST_NULL; } MSXML2::IXMLDOMNodeListPtr pXMLDOMNodeListPtr = NULL; try { pXMLDOMNodeListPtr = m_pXMLDOMDocument->getElementsByTagName(_bstr_t(szNodeName)); if( NULL == pXMLDOMNodeListPtr ) { #ifdef _DEBUG TCHAR szDebugString[MAX_PATH]; memset( szDebugString, 0, sizeof(szDebugString) ); _stprintf( szDebugString, TEXT( "\nCXMLDOMFile::GetAssignNode:Invalid node fetched.\n%s\n" ),(LPCSTR)m_pXMLDOMDocument->parseError->Getreason() ); OutputDebugString( szDebugString ); #endif //assert( false ); RETURNLIST_NULL; } } catch(...) { #ifdef _DEBUG MessageBox( NULL, TEXT("UnKnown error occured!"), TEXT("Error"), MB_OK|MB_ICONSTOP ); #endif if( NULL != pXMLDOMNodeListPtr ) { pXMLDOMNodeListPtr.Release(); pXMLDOMNodeListPtr = NULL; } //assert( false ); RETURNLIST_NULL; } CXMLDOMNodesPtr pRetXMLDOMNodes (new CXMLDOMNodes(pXMLDOMNodeListPtr)); if( NULL != pXMLDOMNodeListPtr ) { pXMLDOMNodeListPtr.Release(); pXMLDOMNodeListPtr = NULL; } int n = pRetXMLDOMNodes->GetCount(); return pRetXMLDOMNodes; } CXMLDOMNodesPtr CXMLDOMFile::SelectNodes( const TCHAR* szNodeXPath ) { //assert( NULL != m_pXMLDOMDocument ); if( NULL == m_pXMLDOMDocument ) { RETURNLIST_NULL; } //assert( NULL != szNodeXPath ); if( NULL == szNodeXPath ) { RETURNLIST_NULL; } MSXML2::IXMLDOMNodeListPtr pXMLDOMNodeList = NULL; try { pXMLDOMNodeList = m_pXMLDOMDocument->selectNodes( _bstr_t( szNodeXPath ) );// if( NULL == pXMLDOMNodeList ) { #ifdef _DEBUG TCHAR szDebugString[MAX_PATH]; memset( szDebugString, 0, sizeof(szDebugString) ); _stprintf( szDebugString,TEXT("\nCXMLDOMFile::selectNodes:Invalid nodes fetched.\n%s\n"),( TCHAR* )m_pXMLDOMDocument->parseError->Getreason() ); OutputDebugString( szDebugString ); #endif //assert( false ); RETURNLIST_NULL; } } catch ( ... ) { #ifdef _DEBUG MessageBox( NULL, TEXT("UnKnown error occured!"), TEXT("Error"), MB_OK|MB_ICONSTOP ); #endif if( NULL != pXMLDOMNodeList ) { pXMLDOMNodeList.Release(); pXMLDOMNodeList = NULL; } //assert( false ); RETURNLIST_NULL; } CXMLDOMNodesPtr pRetXMLDOMNodes ( new CXMLDOMNodes( pXMLDOMNodeList ) ); if( NULL != pXMLDOMNodeList ) { pXMLDOMNodeList.Release(); pXMLDOMNodeList = NULL; } return pRetXMLDOMNodes; } CXMLDOMNodePtr CXMLDOMFile::SelectNodeByAttribute( const TCHAR* szNodeXPath, const TCHAR* szAttributeName , const TCHAR* szAttributeValue ) { assert( NULL != szNodeXPath ); if( NULL == szNodeXPath ){ RETURN_NULL; } assert( NULL != szAttributeName ); if( NULL == szAttributeName ){ RETURN_NULL; } assert( NULL != szAttributeValue ); if( NULL == szAttributeValue ){ RETURN_NULL; } TCHAR szTempNodeXPath[MAX_PATH]; memset( szTempNodeXPath, 0, sizeof( szTempNodeXPath ) ); _tcscpy( szTempNodeXPath, szNodeXPath ); int nLen = ( int )_tcslen( szTempNodeXPath ); assert( nLen > 0 ); if( nLen <= 0 ) // No path { RETURN_NULL; } // with '/' end, added '*' at the last. if( szTempNodeXPath[ nLen-1 ] == TEXT('/') ) { szTempNodeXPath[ nLen ] = TEXT('*'); szTempNodeXPath[ nLen + 1 ] = TEXT('\0'); } // Joint the Attribute name and value: _tcscat( szTempNodeXPath, TEXT("[@") ); _tcscat( szTempNodeXPath, szAttributeName ); _tcscat( szTempNodeXPath, TEXT("=\'") ); _tcscat( szTempNodeXPath, szAttributeValue ); _tcscat( szTempNodeXPath, TEXT("\']") ); OutputDebugString( szTempNodeXPath ); //assert( ( int ) _tcslen( szTempNodeXPath ) > 0 ); return SelectSingleNode( szTempNodeXPath ); } bool CXMLDOMFile::IsRootNode(const CXMLDOMNodePtr &pXMLDOMNodePtr) { CXMLDOMNodePtr TemPtr = GetRoot(); if (*pXMLDOMNodePtr.get() == *TemPtr.get()) { return true; } else { return false; } /*MSXML2::IXMLDOMNodePtr ptRoot = TemPtr->GetNodePtr(); MSXML2::IXMLDOMNodePtr ptNode = pXMLDOMNodePtr->GetNodePtr(); if (ptRoot == ptNode) { return true; }*/ } CString CXMLDOMFile::GetVersion() { CString str; CStdioFile file; if(!file.Open(m_strFileName, CFile::modeRead)) { //MessageBox(CString(_T("打开"))+strPath+_T("失败!")); return str; } CString strTem; file.ReadString(strTem); /*int nPos = strTem.FindOneOf(_T("version")); int nStart = strTem.Find(_T("\""),nPos); strTem.Delete(0,nStart+1); int nEnd = strTem.Find(_T("\""),0); int nLen = strTem.GetLength(); strTem.Delete(nEnd,nLen); file.Close();*/ str = strTem; return str; } CString CXMLDOMFile::GetCodeVersion() { CString str; CStdioFile file; if(!file.Open(m_strFileName, CFile::modeRead)) { //MessageBox(CString(_T("打开"))+strPath+_T("失败!")); return str; } CString strTem; file.ReadString(strTem); int nPos = strTem.Find(_T("\""),0); int nTem = strTem.Find(_T("\""),nPos+1); int nStart = strTem.Find(_T("\""),nTem+1); strTem.Delete(0,nStart+1); int nEnd = strTem.Find(_T("\""),0); int nLen = strTem.GetLength(); strTem.Delete(nEnd,nLen); file.Close(); str = strTem; return str; } void CXMLDOMFile::GetCurNodeXPath(const CXMLDOMNodePtr &ptr,CString &strXPath) { CXMLDOMNodePtr pRoot = GetRoot(); CString strName = pRoot->GetNodeName(); CString strpname = ptr->GetNodeName(); bool bIsRoot = IsRootNode(ptr); if(!bIsRoot) { CXMLDOMNodePtr pXMLDOMNodePtr =ptr->GetParentNode(); if (pXMLDOMNodePtr.get()!=NULL) { GetCurNodeXPath(pXMLDOMNodePtr,strXPath); } } CString strNodeName = ptr->GetNodeName(); bool bIs = IsRootNode(ptr); strXPath +=_T("/")+strNodeName; CString strAttriName = ptr->GetAttributeName(); CString strAttriValue = ptr->GetAttributeValue(strAttriName); if (strAttriName!=_T("")) { strXPath += _T("[@"+strAttriName+_T("=")); if (strAttriValue!=_T("")) { strXPath += _T("'")+strAttriValue+_T("'")+_T("]"); } } return; } void CXMLDOMFile::GetNoteAttriPath(const CXMLDOMNodePtr &pXMLDOMNodePtr,const CString &strAttriName,CString &strXPath) { bool bIsRoot = IsRootNode(pXMLDOMNodePtr); if(!bIsRoot) { CXMLDOMNodePtr pParent =pXMLDOMNodePtr->GetParentNode(); GetNoteAttriPath(pParent,strAttriName,strXPath); } CString strNodeName = pXMLDOMNodePtr->GetAttributeValue(strAttriName); strXPath +=_T("/")+strNodeName; }