📄 xml.cpp
字号:
{
#endif
if ( ParseMatch( pszXML, _T("<?xml version=\"") ) )
{
pszElement = _tcsstr( pszXML, _T("?>") );
if ( ! pszElement ) return FALSE;
pszXML = pszElement + 2;
}
else if ( bHeader ) return NULL;
while ( ParseMatch( pszXML, _T("<!--") ) )
{
pszElement = _tcsstr( pszXML, _T("-->") );
if ( ! pszElement || *pszElement != '-' ) return FALSE;
pszXML = pszElement + 3;
}
if ( ParseMatch( pszXML, _T("<!DOCTYPE") ) )
{
pszElement = _tcsstr( pszXML, _T(">") );
if ( ! pszElement ) return FALSE;
pszXML = pszElement + 1;
}
while ( ParseMatch( pszXML, _T("<!--") ) )
{
pszElement = _tcsstr( pszXML, _T("-->") );
if ( ! pszElement || *pszElement != '-' ) return FALSE;
pszXML = pszElement + 3;
}
pElement = new CXMLElement();
if ( ! pElement->ParseString( pszXML ) )
{
delete pElement;
pElement = NULL;
}
#ifdef _AFX
}
catch ( CException* pException )
{
pException->Delete();
delete pElement;
pElement = NULL;
}
#endif
return pElement;
}
BOOL CXMLElement::ParseString(LPCTSTR& strXML)
{
if ( ! ParseMatch( strXML, _T("<") ) ) return FALSE;
if ( ! ParseIdentifier( strXML, m_sName ) ) return FALSE;
LPCTSTR pszEnd = strXML + _tcslen( strXML );
while ( ! ParseMatch( strXML, _T(">") ) )
{
if ( ParseMatch( strXML, _T("/") ) )
{
return ParseMatch( strXML, _T(">") );
}
if ( ! *strXML || strXML >= pszEnd ) return FALSE;
CXMLAttribute* pAttribute = new CXMLAttribute( this );
if ( pAttribute->ParseString( strXML ) )
{
CString strName( pAttribute->m_sName );
CXMLAttribute* pExisting;
strName.MakeLower();
if ( m_pAttributes.Lookup( strName, XMLVOID(pExisting) ) ) delete pExisting;
m_pAttributes.SetAt( strName, pAttribute );
}
else
{
delete pAttribute;
return FALSE;
}
}
CString strClose = _T("</");
strClose += m_sName + '>';
while ( TRUE )
{
if ( ! *strXML || strXML >= pszEnd ) return FALSE;
LPCTSTR pszElement = _tcschr( strXML, '<' );
if ( ! pszElement || *pszElement != '<' ) return FALSE;
if ( pszElement > strXML )
{
if ( m_sValue.GetLength() && m_sValue.Right( 1 ) != ' ' ) m_sValue += ' ';
m_sValue += StringToValue( strXML, (int)( pszElement - strXML ) );
ASSERT( strXML == pszElement );
if ( strXML != pszElement ) return FALSE;
}
if ( ParseMatch( strXML, strClose ) )
{
break;
}
else if ( ParseMatch( strXML, _T("<!--") ) )
{
pszElement = _tcsstr( strXML, _T("-->") );
if ( ! pszElement || *pszElement != '-' ) return FALSE;
strXML = pszElement + 3;
}
else
{
CXMLElement* pElement = new CXMLElement( this );
if ( pElement->ParseString( strXML ) )
{
m_pElements.AddTail( pElement );
}
else
{
delete pElement;
return FALSE;
}
}
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CXMLElement from bytes
CXMLElement* CXMLElement::FromBytes(BYTE* pByte, DWORD nByte, BOOL bHeader)
{
CString strXML;
if ( nByte >= 2 && ( ( pByte[0] == 0xFE && pByte[1] == 0xFF ) || ( pByte[0] == 0xFF && pByte[1] == 0xFE ) ) )
{
nByte = nByte / 2 - 1;
if ( pByte[0] == 0xFE && pByte[1] == 0xFF )
{
pByte += 2;
for ( DWORD nSwap = 0 ; nSwap < nByte ; nSwap ++ )
{
register CHAR nTemp = pByte[ ( nSwap << 1 ) + 0 ];
pByte[ ( nSwap << 1 ) + 0 ] = pByte[ ( nSwap << 1 ) + 1 ];
pByte[ ( nSwap << 1 ) + 1 ] = nTemp;
}
}
else
{
pByte += 2;
}
#ifdef _UNICODE
CopyMemory( strXML.GetBuffer( nByte ), pByte, nByte * sizeof(TCHAR) );
strXML.ReleaseBuffer( nByte );
#else
int nChars = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)pByte, nByte, NULL, 0, NULL, NULL );
WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)pByte, nByte, strXML.GetBuffer( nChars ), nChars, NULL, NULL );
strXML.ReleaseBuffer( nChars );
#endif
}
else
{
if ( nByte >= 3 && pByte[0] == 0xEF && pByte[1] == 0xBB && pByte[2] == 0xBF )
{
pByte += 3; nByte -= 3;
}
DWORD nWide = MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)pByte, nByte, NULL, 0 );
#ifdef _UNICODE
MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)pByte, nByte, strXML.GetBuffer( nWide ), nWide );
strXML.ReleaseBuffer( nWide );
#else
WCHAR* pWide = new WCHAR[ nWide + 1 ];
MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)pByte, nByte, pWide, nWide );
pWide[ nWide ] = 0;
strXML = pWide;
delete [] pWide;
#endif
}
return FromString( strXML, bHeader );
}
//////////////////////////////////////////////////////////////////////
// CXMLElement from file
CXMLElement* CXMLElement::FromFile(LPCTSTR pszPath, BOOL bHeader)
{
HANDLE hFile = CreateFile( pszPath, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if ( hFile == INVALID_HANDLE_VALUE ) return NULL;
CXMLElement* pXML = FromFile( hFile, bHeader );
CloseHandle( hFile );
return pXML;
}
CXMLElement* CXMLElement::FromFile(HANDLE hFile, BOOL bHeader)
{
DWORD nByte = GetFileSize( hFile, NULL );
if ( nByte > 4096*1024 ) return FALSE;
BYTE* pByte = new BYTE[ nByte ];
ReadFile( hFile, pByte, nByte, &nByte, NULL );
CXMLElement* pXML = FromBytes( pByte, nByte, bHeader );
delete [] pByte;
return pXML;
}
//////////////////////////////////////////////////////////////////////
// CXMLElement equality
BOOL CXMLElement::Equals(CXMLElement* pXML) const
{
if ( this == NULL || pXML == NULL ) return FALSE;
if ( pXML == this ) return TRUE;
if ( m_sName != pXML->m_sName ) return FALSE;
if ( m_sValue != pXML->m_sValue ) return FALSE;
if ( GetAttributeCount() != pXML->GetAttributeCount() ) return FALSE;
if ( GetElementCount() != pXML->GetElementCount() ) return FALSE;
for ( POSITION pos = GetAttributeIterator() ; pos ; )
{
CXMLAttribute* pAttribute1 = GetNextAttribute( pos );
CXMLAttribute* pAttribute2 = pXML->GetAttribute( pAttribute1->m_sName );
if ( pAttribute2 == NULL ) return FALSE;
if ( ! pAttribute1->Equals( pAttribute2 ) ) return FALSE;
}
POSITION pos1 = GetElementIterator();
POSITION pos2 = pXML->GetElementIterator();
for ( ; pos1 && pos2 ; )
{
CXMLElement* pElement1 = GetNextElement( pos1 );
CXMLElement* pElement2 = pXML->GetNextElement( pos2 );
if ( pElement1 == NULL || pElement2 == NULL ) return FALSE;
if ( ! pElement1->Equals( pElement2 ) ) return FALSE;
}
if ( pos1 != NULL || pos2 != NULL ) return FALSE;
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CXMLElement recursive word accumulation
CString CXMLElement::GetRecursiveWords()
{
CString strWords;
AddRecursiveWords( strWords );
strWords.TrimLeft();
strWords.TrimRight();
return strWords;
}
void CXMLElement::AddRecursiveWords(CString& strWords)
{
for ( POSITION pos = GetAttributeIterator() ; pos ; )
{
CXMLAttribute* pAttribute = GetNextAttribute( pos );
CString strText = pAttribute->GetName();
if ( strText.Find( ':' ) >= 0 ) continue;
if ( strText.CompareNoCase( _T("SHA1") ) == 0 ) continue; // NOTE: Shareaza Specific
if ( strWords.GetLength() ) strWords += ' ';
strWords += pAttribute->GetValue();
}
for ( pos = GetElementIterator() ; pos ; )
{
GetNextElement( pos )->AddRecursiveWords( strWords );
}
if ( m_sValue.GetLength() )
{
if ( strWords.GetLength() ) strWords += ' ';
strWords += m_sValue;
}
}
//////////////////////////////////////////////////////////////////////
// CXMLElement serialize
#ifdef _AFX
void CXMLElement::Serialize(CArchive& ar)
{
CXMLNode::Serialize( ar );
if ( ar.IsStoring() )
{
ar.WriteCount( GetAttributeCount() );
for ( POSITION pos = GetAttributeIterator() ; pos ; )
{
GetNextAttribute( pos )->Serialize( ar );
}
ar.WriteCount( GetElementCount() );
for ( pos = GetElementIterator() ; pos ; )
{
GetNextElement( pos )->Serialize( ar );
}
}
else
{
for ( int nCount = (int)ar.ReadCount() ; nCount > 0 ; nCount-- )
{
CXMLAttribute* pAttribute = new CXMLAttribute( this );
pAttribute->Serialize( ar );
CString strName( pAttribute->m_sName );
strName.MakeLower();
m_pAttributes.SetAt( strName, pAttribute );
}
for ( nCount = (int)ar.ReadCount() ; nCount > 0 ; nCount-- )
{
CXMLElement* pElement = new CXMLElement( this );
pElement->Serialize( ar );
m_pElements.AddTail( pElement );
}
}
}
#endif
//////////////////////////////////////////////////////////////////////
// CXMLAttribute construction
LPCTSTR CXMLAttribute::xmlnsSchema = _T("http://www.w3.org/2001/XMLSchema");
LPCTSTR CXMLAttribute::xmlnsInstance = _T("http://www.w3.org/2001/XMLSchema-instance");
LPCTSTR CXMLAttribute::schemaName = _T("xsi:noNamespaceSchemaLocation");
CXMLAttribute::CXMLAttribute(CXMLElement* pParent, LPCTSTR pszName) : CXMLNode( pParent, pszName )
{
m_nNode = xmlAttribute;
}
CXMLAttribute::~CXMLAttribute()
{
}
//////////////////////////////////////////////////////////////////////
// CXMLAttribute clone
CXMLAttribute* CXMLAttribute::Clone(CXMLElement* pParent)
{
CXMLAttribute* pClone = new CXMLAttribute( pParent, m_sName );
pClone->m_sValue = m_sValue;
return pClone;
}
//////////////////////////////////////////////////////////////////////
// CXMLAttribute to string
void CXMLAttribute::ToString(CString& strXML)
{
strXML += m_sName + _T("=\"");
ValueToString( m_sValue, strXML );
strXML += '\"';
}
//////////////////////////////////////////////////////////////////////
// CXMLAttribute from string
BOOL CXMLAttribute::ParseString(LPCTSTR& strXML)
{
if ( ! ParseIdentifier( strXML, m_sName ) ) return FALSE;
if ( ! ParseMatch( strXML, _T("=") ) ) return FALSE;
if ( ParseMatch( strXML, _T("\"") ) )
{
LPCTSTR pszQuote = _tcschr( strXML, '\"' );
if ( ! pszQuote || *pszQuote != '\"' ) return FALSE;
m_sValue = StringToValue( strXML, (int)( pszQuote - strXML ) );
return ParseMatch( strXML, _T("\"") );
}
else if ( ParseMatch( strXML, _T("'") ) )
{
LPCTSTR pszQuote = _tcschr( strXML, '\'' );
if ( ! pszQuote || *pszQuote != '\'' ) return FALSE;
m_sValue = StringToValue( strXML, (int)( pszQuote - strXML ) );
return ParseMatch( strXML, _T("\'") );
}
else
{
return FALSE;
}
}
//////////////////////////////////////////////////////////////////////
// CXMLAttribute equality
BOOL CXMLAttribute::Equals(CXMLAttribute* pXML) const
{
if ( this == NULL || pXML == NULL ) return FALSE;
if ( pXML == this ) return TRUE;
if ( m_sName != pXML->m_sName ) return FALSE;
if ( m_sValue != pXML->m_sValue ) return FALSE;
return TRUE;
}
//////////////////////////////////////////////////////////////////////
// CXMLAttribute serialize
#ifdef _AFX
void CXMLAttribute::Serialize(CArchive& ar)
{
CXMLNode::Serialize( ar );
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -