xmlsupport.cpp

来自「用bcg库编写的java IDE 源码」· C++ 代码 · 共 363 行

CPP
363
字号
#include "stdafx.h"
#include "xmlsupport.h"

 
CMiniXMLParser::CMiniXMLParser(char* pBuf,int nLength/*,TYPE* pSubscriber*/)
{
     m_bAtomicElement = false;
	 m_nIndex         = 0;
	 m_nContext       = 0;
	 m_nBufLength     = nLength;
	 m_lszpBuf        = pBuf;
	// m_pSubscriber    = pSubscriber;
}

CMiniXMLParser::~CMiniXMLParser()
{
   for(POSITION nPos = m_lParsedTree.GetHeadPosition(); nPos !=NULL;)
	        delete m_lParsedTree.GetNext(nPos);
}

bool CMiniXMLParser::parse(){return mainEntryPoint();}

XMLELEMENT_LIST* CMiniXMLParser::getXmlTree(){return &m_lParsedTree;}

  bool CMiniXMLParser::leftTag(XMLelement* pElement)
  {
    if(!getNextToken())return false;
	if(m_strToken.Compare((LPCTSTR)"<") == 0)
	{
      if(tagName())
	  {
	    pElement->m_strElementName = m_strToken;
        if(attributesOpt(pElement))
		{
          m_nContext = 1;
          if(!getNextToken())return false;
          m_nContext = 0;

		  if(m_strToken.Compare((LPCTSTR)">") == 0)
		  {
		    //**m_stTagNames.Push(pElement->m_strElementName);
            return true;
		  }
		  else
		  if(m_strToken.Compare((LPCTSTR)"/>") == 0)
		  {
		    m_bAtomicElement = true;
            return true;
		  }
		}
	  }
	}return false;
  }


  bool CMiniXMLParser::attributesOpt(XMLelement*pElement)
  {
    while(true)
	{
      m_strToken.Empty();
      if(m_nIndex<m_nBufLength)
	  {
        for(m_nIndex;m_nIndex<m_nBufLength;m_nIndex++)
		{
		  if(!iswspace(m_lszpBuf[m_nIndex]))break;
		}
        if(!isalpha(m_lszpBuf[m_nIndex])&&(m_lszpBuf[m_nIndex] != '_'))return true;
	  }

      if(attributeName())
	  {
	    CString strAttribName = m_strToken;
        if(!getNextToken())return false;
	    if(m_strToken.Compare((LPCTSTR)"=") == 0)
	    {      
          if(attributeValue())
		  {
            XMLattribute* attrib = new XMLattribute;
			attrib->m_strName  = strAttribName;
			attrib->m_strValue = m_strToken;
            pElement->m_lAttributes.AddTail(attrib);
		    //return true;
		  }	   
	    }
	  }
	}return false;
  }

  bool CMiniXMLParser::rightTag()
  {
    m_nContext = 1;
    if(!getNextToken())return false;
	m_nContext = 0;

	if(m_strToken.Compare((LPCTSTR)"</") == 0)
	{
      if(tagName())
	  {
	    /**
		CString strTagName;
		m_stTagNames.Pop(strTagName);
		if(strTagName.Compare(m_strToken) != 0)
		{
          //report error
          return false;
		}
        **/
        m_nContext = 1;
        if(!getNextToken())return false;
        m_nContext = 0;

		if(m_strToken.Compare((LPCTSTR)">") == 0)
		{
		  
          return true;
		}
	  }
	}return false;
  }

  bool CMiniXMLParser::element(XMLelement* &pParent)
  {
    XMLelement* pElement= new XMLelement;
    
    if(leftTag(pElement))
	{
      if(m_bAtomicElement)
	  {
	    pElement->m_bAtomic = TRUE;
        m_bAtomicElement = false;
		if(pParent == NULL)
         pParent  = pElement;
		else
		 pParent->m_lNestedElements.AddTail(pElement);
		return true;
	  }
      
      if(elementRest(pElement))
	  {
        if(rightTag())
		{
		  if(pParent == NULL)
           pParent  = pElement;
		  else
		   pParent->m_lNestedElements.AddTail(pElement);
          return true;
		}
	  }
	}
	delete pElement;
	return false;
  }

  bool CMiniXMLParser::elementRest(XMLelement* pElement)
  {
    int nIndex = m_nIndex;
    while(getNextToken())
	{	  
      if(m_strToken.Compare((LPCTSTR)"<") == 0)
	  {
        m_nIndex = nIndex;
		if(!element(pElement))return false;
	  }
	  else
	  if(m_strToken.Compare((LPCTSTR)"</") == 0)
	  {
        m_nIndex = nIndex;
		return true;
	  }
	  else
	  pElement->m_strElementValue += m_strToken;

	  nIndex = m_nIndex;
	}return false;
  }
  
  bool CMiniXMLParser::attributeName(){return identfier();}

  bool CMiniXMLParser::tagName(){return identfier();}

  bool CMiniXMLParser::attributeValue(){return stringLiteral();}

  bool CMiniXMLParser::stringLiteral()
  {
    m_strToken.Empty();
    if(m_nIndex<m_nBufLength)
	{
       for(m_nIndex;m_nIndex<m_nBufLength;m_nIndex++)
	   {
		  if(!iswspace(m_lszpBuf[m_nIndex]))
		        break;
       }
        if(m_lszpBuf[m_nIndex] != '\"')return false;
	   //m_strToken = '\"';
	   ++m_nIndex;
	}
    
	for(m_nIndex; m_nIndex<m_nBufLength; m_nIndex++)
	{
      if(m_lszpBuf[m_nIndex] == '\"')
	  {
	    ++m_nIndex;
        //m_strToken += '\"';
		m_strToken.TrimLeft();m_strToken.TrimRight();
		return true;
	  }
	  else
	  m_strToken += m_lszpBuf[m_nIndex];
	}return false;
  }

  bool CMiniXMLParser::identfier()
  {
    if(!getNextToken())return false;
    //first charracter must be a letter or underscore
    if(!isalpha(m_strToken[0])&&m_strToken[0] != '_')return false;

    //scan for invalid characters
    int nLen = m_strToken.GetLength();
    for(int i=0; i<nLen; i++)
    if(!__iscsym(m_strToken[i]))return false;

    return true;
  }

  bool CMiniXMLParser::getNextToken()
  {
     while(getNextTokenImpl())
     {
       if(m_strToken.Compare("<!--") == 0)
	   {
         if(comment())continue;}
       
	   return true;
     }return false;
  }



bool CMiniXMLParser::getNextTokenImpl()
{
    m_strToken.Empty();
	for(m_nIndex; m_nIndex<m_nBufLength; m_nIndex++)
	{
	  if(m_lszpBuf[m_nIndex] == '=')
	  {
        if(!m_strToken.IsEmpty())
          return true;

		++m_nIndex;
		m_strToken = '=';
		return true;
	  }
	  else
	  if(m_lszpBuf[m_nIndex] == '/' &&
	  (((m_nIndex+1)<m_nBufLength)&&(m_lszpBuf[m_nIndex+1]=='>')))
	  {
        if(!m_strToken.IsEmpty())
          return true;

        m_nIndex += 2;
		m_strToken = "/>";
		if(m_nContext == 1)
		return true;
	  }
	  else
	  if(m_lszpBuf[m_nIndex] == '<' &&
	  (((m_nIndex+1)<m_nBufLength)&&(m_lszpBuf[m_nIndex+1]=='/')))
	  {
        if(!m_strToken.IsEmpty())
          return true;

        m_nIndex += 2;
		m_strToken = "</";
		//if(m_nContext == 1)
		return true;
	  }
	  else
	  if((m_lszpBuf[m_nIndex] == '<' )&&
	     ((m_nIndex+3)<m_nBufLength)&&
	     (m_lszpBuf[m_nIndex+1]=='!')&&
	     (m_lszpBuf[m_nIndex+2]=='-')&&
		 (m_lszpBuf[m_nIndex+3]=='-'))
	  {
        if(!m_strToken.IsEmpty())
          return true;

        m_nIndex += 4;
		m_strToken = "<!--";
		//if(m_nContext == 1)
		return true;
	  }
	  else
	  if((m_lszpBuf[m_nIndex] == '-') &&
	     ((m_nIndex+2)<m_nBufLength)&&
		 (m_lszpBuf[m_nIndex+1]=='-')&&
	     (m_lszpBuf[m_nIndex+2]=='>'))
	  {
        if(!m_strToken.IsEmpty())
          return true;

        m_nIndex += 3;
		m_strToken = "-->";
		//if(m_nContext == 1)
		return true;
	  }
	  else
      if(m_lszpBuf[m_nIndex] == '<')//this position within the if/else atructure matters
	  {
        if(!m_strToken.IsEmpty())
          return true;

		++m_nIndex;
		m_strToken = '<';
		return true;
	  }
	  else
	  if(m_lszpBuf[m_nIndex] == '>')
	  {
        if(!m_strToken.IsEmpty())
          return true;

		++m_nIndex;
		m_strToken += '>';
		if(m_nContext == 1)
		return true;
	  }
	  else
	  if(iswspace(m_lszpBuf[m_nIndex]))
	  {
        if(!m_strToken.IsEmpty())
          return true;
	  }
	  else
	  m_strToken += m_lszpBuf[m_nIndex];
	}
    if(!m_strToken.IsEmpty())return true;
    return false;
}

bool CMiniXMLParser::comment()
{
   while(getNextTokenImpl())
   {
     if(m_strToken.Compare("-->") == 0)
	   return true;
   }return false;
}

bool CMiniXMLParser::mainEntryPoint()
{
    XMLelement* pElement = NULL;
    while(element(pElement))
	{
	  m_lParsedTree.AddTail(pElement);
      for(m_nIndex;m_nIndex<m_nBufLength;m_nIndex++)
	  {
		if(!iswspace(m_lszpBuf[m_nIndex]))break;
      }
      if(m_nIndex>=m_nBufLength) return true;
	  pElement = NULL;
	}return false;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?