Files
envi-code/SourceCode/Code2026/tg_shs/shs_kernal/XMLDOMFile.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

708 lines
17 KiB
C++

#include "stdafx.h"
#include "XMLDOMFile.h"
#include "XMLDOMNode.h"
#include "XMLDOMNodes.h"
#include <assert.h>
#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 (;i<nLen;i++)
{
NodeAttriBute nodeInfo = nodeInfoAry.GetAt(i);
hr = pXMLDOMElement->setAttribute( _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("<?xml version=\"1.0\"?>\n<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n<xsl:output method = \"xml\" omit-xml-declaration = \"yes\" indent = \"yes\"/>\n<xsl:template match=\"/ | @* | node()\">\n<xsl:copy>\n<xsl:apply-templates select=\"@* | node()\"/>\n</xsl:copy>\n</xsl:template>\n</xsl:stylesheet>");
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("<?xml version=\"1.0\" encoding=\"utf-8\"?>\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 ;i<nCount;i++)
{
CString strNodeAttriTem,strNodeAttriName;
pXMLDOMNodePtr = pXMLDOMNodesPtr->GetItem(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;
}