www.pudn.com > ParseXML.rar > XmlFile.cpp
#include "StdAfx.h" #include "xmlfile.h" //#include///////////////////////////////////////////////////////////////////// // class CDataBuffer CDataBuffer::CDataBuffer() { m_pDataBuffer = NULL; m_nDataSize = 0; m_nReadPos = 0; } CDataBuffer::~CDataBuffer() { if(m_pDataBuffer != NULL) { delete m_pDataBuffer; } } BOOL CDataBuffer::CreateFromFile(LPCTSTR lpszFilePath) { CFile file; if(!file.Open(lpszFilePath, CFile::modeRead)) { return FALSE; } if(m_pDataBuffer != NULL) delete m_pDataBuffer; m_nDataSize = (DWORD)file.GetLength(); m_pDataBuffer = new BYTE[m_nDataSize]; if(file.Read(m_pDataBuffer, m_nDataSize) != m_nDataSize) { delete m_pDataBuffer; file.Close(); return FALSE; } m_nReadPos = 0; return TRUE; } void CDataBuffer::FreeBuffer() { if(m_pDataBuffer != NULL) { delete m_pDataBuffer; } m_nDataSize = 0; m_nReadPos = 0; } BOOL CDataBuffer::ReadByte(BYTE& ch) { if(m_nReadPos < m_nDataSize) { ch = m_pDataBuffer[m_nReadPos]; m_nReadPos++; return TRUE; } return FALSE; } void CDataBuffer::GoBack(DWORD nCount) { if(m_nReadPos >= (DWORD)nCount) m_nReadPos -= nCount; else m_nReadPos = 0; } void CDataBuffer::CopyData(void* pBuffer, DWORD nPos, DWORD nLen) { if(pBuffer != NULL && m_pDataBuffer != NULL && nPos + nLen < m_nDataSize) { memcpy(pBuffer, m_pDataBuffer + nPos, nLen); } } ///////////////////////////////////////////////////////////////////// // class CXmlTag CXmlTag::CXmlTag() { m_pBuffer = NULL; m_nTagType = -1; } CXmlTag::~CXmlTag() { if(m_pBuffer != NULL) { delete m_pBuffer; } } BOOL CXmlTag::IsXmlVersionTag() { if(m_pBuffer == NULL) return FALSE; if(strstr((char *)m_pBuffer, "') { break; } } DWORD to = data.GetPosition(); m_pBuffer = new BYTE[to - from + 1]; data.CopyData(m_pBuffer, from, to - from); m_pBuffer[to - from] = '\0'; if(m_nTagType == 2) { if(to - from > 2) { if(m_pBuffer[1] == '/') { m_nTagType = 4; } else if(m_pBuffer[to - from - 2] == '/') { m_nTagType = 3; } } else { m_nTagType = -1; } } return m_nTagType != -1; } BOOL CXmlTag::IsSameName(char* name) { if(m_pBuffer != NULL && strlen((char*)m_pBuffer) - strlen(name) >= 2) { if(strstr((char*)m_pBuffer, name) == (char*)(m_pBuffer + 1) && ( m_pBuffer[strlen(name) + 1] == ' ' || m_pBuffer[strlen(name) + 1] == '/' || m_pBuffer[strlen(name) + 1] == '>' )) { return TRUE; } } return FALSE; } int CXmlTag::GetAttributeLen(char* name) { if(m_pBuffer != NULL && (m_nTagType == 2 || m_nTagType == 3)) { char* substr = new char[strlen(name) + 2]; strcpy(substr, name); substr[strlen(name)] = '='; substr[strlen(name) + 1] = '\0'; char* str = strstr((char *)m_pBuffer, substr); if(str != NULL) { int pos = 0; while(str[pos] != '\0' && str[pos] != '\t' && str[pos] != ' ' && str[pos] != '/' && str[pos] != '>') pos++; return pos; } } return 0; } int CXmlTag::GetAttribute(char* name, char*value, int len) { if(m_pBuffer != NULL && (m_nTagType == 2 || m_nTagType == 3)) { char* substr = new char[strlen(name) + 2]; strcpy(substr, name); substr[strlen(name)] = '='; substr[strlen(name) + 1] = '\0'; char* str = strstr((char *)m_pBuffer, substr); if(str != NULL) { int pos = 0; while(str[pos] != '\0' && str[pos] != '\t' && str[pos] != ' ' && str[pos] != '/' && str[pos] != '>'&& pos < len - 1) { value[pos] = str[pos]; pos++; } value[pos] = '\0'; return pos; } } return 0; } int CXmlTag::GetValueLen() { CXmlTag* pTag = (CXmlTag *)m_pLeftNode; while(pTag != NULL && pTag->m_nTagType != 0) pTag = (CXmlTag *)pTag->m_pRightNode; if(pTag != 0 && pTag->m_pBuffer != NULL) { return (int)strlen((char *)pTag->m_pBuffer); } return 0; } int CXmlTag::GetValue(char* value, int len) { CXmlTag* pTag = (CXmlTag *)m_pLeftNode; while(pTag != NULL && pTag->m_nTagType != 0) pTag = (CXmlTag *)pTag->m_pRightNode; if(pTag != 0 && pTag->m_pBuffer != NULL) { int i = 0; for(; i < len && pTag->m_pBuffer[i] != '\0'; i++) { value[i] = pTag->m_pBuffer[i]; } value[i] = '\0'; return i; } return 0; } CString CXmlTag::GetValue() { int len = GetValueLen(); char* buffer = new char[len + 1]; GetValue(buffer, len); CStringA strTmpA = buffer; CString strTmp = CA2T(buffer); return strTmp; } ///////////////////////////////////////////////////////////////////// // class CXmlFile CXmlFile::CXmlFile(void) { } CXmlFile::~CXmlFile(void) { } BOOL CXmlFile::Open(LPCTSTR lpszFilePath) { CDataBuffer data; if(!data.CreateFromFile(lpszFilePath)) { return FALSE; } if(!ParseXml(data)) { return FALSE; } return TRUE; } void CXmlFile::Close() { m_XmlNodeTree.FreeTree(); } BOOL CXmlFile::ParseXml(CDataBuffer& data) { CXmlTag tag; if(!tag.Read(data)) { return FALSE; } if(!tag.IsXmlVersionTag()) { return FALSE; } if(!ParseXml(data, m_XmlNodeTree.GetRootNode())) { return FALSE; } return TRUE; } BOOL CXmlFile::ParseXml(CDataBuffer& data, CNode* pParentNode) { while(data.IsEOF()) { CXmlTag* tag = new CXmlTag(); //读入一个TAG if(tag->Read(data)) { BYTE nTagType = tag->GetTagType(); if(nTagType == 0 || nTagType == 3) { m_XmlNodeTree.InsertChildNode(tag, pParentNode); } else if(nTagType == 1) { //丢弃不要 delete tag; } else if(nTagType == 2) { m_XmlNodeTree.InsertChildNode(tag, pParentNode); if(!ParseXml(data, tag)) { delete tag; return FALSE; } } else //nTagType == 4 { delete tag; return TRUE; } } else { delete tag; return FALSE; } } return TRUE; } CXmlTag* CXmlFile::GetRootElement() { return (CXmlTag *)m_XmlNodeTree.GetRootNode()->m_pLeftNode; } int CXmlFile::GetChildElementCount(CXmlTag* pParent) { int n = 0; if(pParent != NULL) { CNode* p = pParent->m_pLeftNode; while(p != NULL) { n++; p = p->m_pRightNode; } } return n; } CXmlTag* CXmlFile::GetChildElement(CXmlTag* pParent, int nIndex) { if(pParent != NULL) { int n = 0; CNode* p = pParent->m_pLeftNode; while(p != NULL && n != nIndex) { n++; p = p->m_pRightNode; } return (CXmlTag *)p; } return NULL; } CXmlTag* CXmlFile::FindChildElement(CXmlTag* pParent, char* name) { if(pParent != NULL && name != NULL) { CXmlTag* p = (CXmlTag *)pParent->m_pLeftNode; while(p != NULL && !p->IsSameName(name)) { p = (CXmlTag *)p->m_pRightNode; } return p; } return NULL; }