XMLParser.cpp
上传用户:hysujiao87
上传日期:2007-12-02
资源大小:156k
文件大小:9k
- // XMLParser.cpp: implementation of the CXMLParser class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "XMLParser.h"
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- #define TEMP_BUF_LEN 1024
- CXMLParser::CXMLParser() :
- m_pos(0),
- m_root(NULL)
- {
- m_version = "xml version="1.0"";
- }
- CXMLParser::~CXMLParser()
- {
- FreeXML();
- FreeTree();
- }
- int CXMLParser::LoadXML(BYTE* pBuf, DWORD nSize)
- {
- _ASSERTE(pBuf != NULL);
- if (pBuf == NULL)
- return -1;
- FreeTree();
- LPTSTR xmlBuffer = m_xml.GetBuffer(nSize + 1);
- memcpy((void*)xmlBuffer, pBuf, nSize);
- xmlBuffer[nSize] = ' ';
- m_xml.ReleaseBuffer();
- int result = ParseVersion();
- if (result != 0)
- return result;
-
- return ParseRoot();
- }
- int CXMLParser::LoadXML(LPCTSTR pathXML)
- {
- CByteArray xmlBuffer;
- try{
- CFile file(pathXML, CFile::modeRead | CFile::typeBinary);
- int length = (int)file.GetLength();
- if (length < 0)
- {
- TRACE("ERROR: Try to load a too big XML file.");
- file.Close();
- return -1;
- }
- xmlBuffer.SetSize(length);
-
- BYTE *xmlData = xmlBuffer.GetData();
- _ASSERTE(xmlData != NULL);
- if (xmlData == NULL)
- {
- TRACE("ERROR: Memory not enought.");
- file.Close();
- return -1;
- }
-
- file.Read(xmlData, length);
- file.Close();
- }
- catch (CFileException *fe) {
- fe->ReportError();
- fe->Delete();
- }
-
- return LoadXML(xmlBuffer.GetData(), (DWORD)xmlBuffer.GetSize());
- }
- int CXMLParser::ParseVersion()
- {
- //Try to find the start of the version tag.
- int version_start = m_xml.Find(_T("<?"), 0);
- if (version_start == -1)
- return -1;
- m_pos = version_start + 2;
- int version_finish = m_xml.Find(_T("?>"), m_pos);
- if (version_finish == -1)
- return -1;
- m_version = m_xml.Mid(m_pos, version_finish - m_pos);
- m_pos = version_finish + 2;
- return 0;
- }
- int CXMLParser::BuildVersion()
- {
- CString version_str = "<?" + m_version + "?>rn";
- m_xml += version_str;
- return 0;
- }
- int CXMLParser::BuildXML()
- {
- FreeXML();
-
- int ret = 0;
- if ( (ret = BuildVersion()) != 0)
- return ret;
- return m_root->BuildElement(m_xml);
- }
- /*BOOL CXMLParser::ParseEntities(CCString& value)
- {
- static TCHAR AMP_REF[] = _T("&");
- static TCHAR LT_REF[] = _T("<");
- static TCHAR GT_REF[] = _T(">");
- static TCHAR QUOT_REF[] = _T(""");
- static TCHAR APOS_REF[] = _T("'");
- static TCHAR AMP[] = _T("&");
- static TCHAR LT[] = _T("<");
- static TCHAR GT[] = _T(">");
- static TCHAR QUOT[] = _T(""");
- static TCHAR APOS[] = _T("");
- static LPCTSTR szEntitiesRef[] = {AMP_REF, LT_REF, GT_REF, QUOT_REF, APOS_REF};
- static LPCTSTR szEntities[] = {AMP, LT, GT, QUOT, APOS};
-
- for(int i = 0; i < sizeof(szEntitiesRef) / sizeof(LPCTSTR); i++)
- {
- int nPos = 0;
- do
- {
- // Try to find the entities reference.
- nPos = value.Find(szEntitiesRef[i], nPos);
- if (nPos != -1)
- {
- // Replace the reference with the entities.
- value.Delete(nPos, _tcslen(szEntitiesRef[i]));
- value.Insert(nPos, szEntities[i]);
- nPos += _tcslen(szEntities[i]);
- }
- }while(nPos != -1);
- }
- return TRUE;
- }
- */
- int CXMLParser::FreeTree()
- {
- if (m_root)
- delete m_root;
- m_root = NULL;
-
- m_version = "xml version="1.0"";
- m_pos = 0;
- return 0;
- }
- int CXMLParser::FreeXML()
- {
- m_xml.Empty();
- m_pos = 0;
- return 0;
- }
- int CXMLParser::findNextTag(CString &tagName, CString &beforeTag)
- {
- tagName.Empty(); beforeTag.Empty();
- int beforeTagStart = findFirstNotOf(m_xml, _T("trn "), m_pos, 4);
- if (beforeTagStart == -1)
- return -1;
- int beforeTagFinish = m_xml.Find("<", beforeTagStart);
- if (beforeTagFinish == -1)
- return -1;
-
- if (beforeTagFinish - beforeTagStart > 0)
- {
- beforeTag = m_xml.Mid(beforeTagStart,
- beforeTagFinish - beforeTagStart);
- beforeTag.TrimRight();
- }
-
- // Find the tag finish position.
- int tag_start = beforeTagFinish;
- int tag_finish = m_xml.Find(">", tag_start);
- if (tag_finish == -1)
- return -1;
-
- tagName = m_xml.Mid(tag_start + 1, tag_finish - tag_start - 1);
- m_pos = tag_finish + 1;
- return 0;
- }
- int CXMLParser::ParseElement(CElement* element)
- {
- _ASSERTE(element != NULL);
- if (element == NULL)
- return -1;
- while(m_pos < m_xml.GetLength())
- {
- CString tagName;
- CString beforeTag;
- if (findNextTag(tagName, beforeTag) == -1)
- {
- TRACE("Error: without a finish tag for <%s>.n", element->get_tag());
- return -1;
- }
- if (element->get_content().IsEmpty())
- element->set_content(beforeTag);
-
- // Is a end-tag?
- if (tagName[0] == '/')
- {
- // Remove the '/' character.
- CString end_tagName;
-
- end_tagName = tagName;
- end_tagName.Delete(0, 1);
-
- if (element->get_tag() != end_tagName)
- {
- TRACE("Can't find a end tag for <%s>.n", element->get_tag());
- return -1;
- }
-
- return 0;
- }
- CElement* sub_element = new CElement(element);
- if (!sub_element)
- return -1;
-
- // Is it a empty tag?
- if (tagName[tagName.GetLength() - 1] == '/')
- {
- tagName.Delete(tagName.GetLength() - 1, 1);
-
- CString actualTagName;
- CMapStringToString attribute;
- if (ParseAttribute(tagName, actualTagName, sub_element->_attribute) != 0)
- return -1;
-
- sub_element->set_tag(actualTagName);
- continue ;
- }
- CString actualTagName;
- CMapStringToString attribute;
- if (ParseAttribute(tagName, actualTagName, sub_element->_attribute) != 0)
- return -1;
- sub_element->set_tag(actualTagName);
- if (ParseElement(sub_element) != 0)
- return -1;
- }
- TRACE("Error: without a finish tag for <%s>.n", element->get_tag());
- return -1;
- }
- int CXMLParser::EnumerateElements(LPENUM_CALLBACK_FUNC pFunc)
- {
- _ASSERTE(pFunc != NULL);
- if (!pFunc)
- return -1;
- return m_root->Enumerate(pFunc);
- }
- int CXMLParser::findFirstNotOf(CString &str, LPCTSTR array, int start, int arraySize)
- {
- int result = start;
- while(result < str.GetLength())
- {
- BOOL bEqual = FALSE;
- for (int i = 0; i < arraySize; i++)
- {
- if (str[result] == array[i])
- bEqual = TRUE;
- }
- if (bEqual == FALSE)
- return result;
- result++;
- }
- return -1;
- }
- int CXMLParser::ParseRoot()
- {
- // Find the root start tag.
- int tag_start = findFirstNotOf(m_xml, _T("trn "), m_pos, 4);
-
- // Find the next tag start position (it is the content part finish also).
- char temp = m_xml[tag_start];
- if (m_xml[tag_start] != _T('<'))
- {
- TRACE("Invalid XML format.n");
- return -1;
- }
-
- int tag_finish = m_xml.Find(_T('>'), tag_start);
- if (tag_finish == -1 || tag_finish - tag_start <= 1)
- {
- TRACE("Invalid root tag name.n");
- return -1;
- }
- CString tagName = m_xml.Mid(tag_start + 1, tag_finish - tag_start - 1);
- set_root(new CElement(NULL));
- get_root()->set_tag(tagName);
- m_pos = tag_finish + 1;
- return ParseElement(m_root);
- }
- int CXMLParser::ParseAttribute(LPCTSTR tagString, CString &tagName, CMapStringToString &attribute)
- {
- _ASSERTE(tagString != NULL);
- if (tagString == NULL)
- return -1;
- attribute.RemoveAll();
- CString tempSting = tagString;
- tempSting.TrimLeft(); tempSting.TrimRight();
- int firstSpacePos = tempSting.FindOneOf(_T(" trn"));
- if (firstSpacePos == -1)
- {
- tagName = tempSting;
- return 0;
- }
- tagName = tempSting.Left(firstSpacePos);
- int startPos = firstSpacePos + 1;
- int equalPos = tempSting.Find(_T('='), startPos);
- while (equalPos != -1)
- {
- CString attributeName = tempSting.Mid(startPos, equalPos - startPos);
- attributeName.TrimLeft(); attributeName.TrimRight();
- int leftInvertedCommasPos = tempSting.Find(_T('"'), equalPos + 1);
- if (leftInvertedCommasPos == -1)
- return -1;
- int rightInvertedCommasPos = tempSting.Find(_T('"'), leftInvertedCommasPos + 1);
- if (rightInvertedCommasPos == -1)
- return -1;
- CString attributeValue = tempSting.Mid(leftInvertedCommasPos + 1, rightInvertedCommasPos - leftInvertedCommasPos - 1);
- attributeValue.TrimLeft(); attributeValue.TrimRight();
- attribute.SetAt(attributeName, attributeValue);
- startPos = rightInvertedCommasPos + 1;
- equalPos = tempSting.Find(_T('='), startPos);
- }
- if (startPos <= tempSting.GetLength() - 1)
- return -1;
- return 0;
- }
- CElement *CXMLParser::createElement(LPCTSTR tag, LPCTSTR content)
- {
- _ASSERTE(tag != NULL && content != NULL);
- if (tag == NULL || content == NULL)
- return NULL;
- CElement *element = new CElement(NULL);
- if (element == NULL)
- return NULL;
- element->set_tag(tag);
- element->set_content(content);
- return element;
- }