⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlparser.cpp

📁 利用XML来作为Makefile的make工具源代码.
💻 CPP
字号:
/**
*CVS Log info
*$Log: XMLParser.cpp,v $
*Revision 1.3  2002/05/09 03:10:49  ddiego
*merged over code from development branch devmain-0-5-1a into the main CVS trunk
*
*Revision 1.2.4.1  2002/03/27 04:13:21  cesarmello
*Linux bugfixes
*
*Revision 1.2  2002/03/15 16:33:22  ddiego
*gcc compile fixes
*
*Revision 1.1  2002/02/25 05:01:53  ddiego
*added the xmake project
*
*Revision 1.7  2002/01/24 01:46:49  ddiego
*added a cvs "log" comment to the top of all files in vcf/src and vcf/include
*to facilitate change tracking
*
*/

//XMLParser.h

#include "StdAfx.h"
#include "XMLParser.h"
#include <algorithm>


String XMLAttr::toString()
{
	String result = " " + getName() + "=\"" + getValue() + "\" "; 
	return result;
}


XMLNode::XMLNode( const String& name, XMLNode* parentNode )
{
	m_name = name;
	m_parentNode = parentNode;
	m_attrsContainer.initContainer( m_attrs );
	m_childNodesContainer.initContainer( m_childNodes );

	if ( NULL != parentNode ) {
		parentNode->addChildNode( this );
	}
}


XMLNode::XMLNode( const XMLNode& node ) 
{
	m_name = node.m_name;
	m_parentNode = node.m_parentNode;
	m_CDATA = node.m_CDATA;
	m_attrs = node.m_attrs;
	//m_childNodes = node.m_childNodes;
	std::vector<XMLNode*>::const_iterator it = node.m_childNodes.begin();
	while ( it != m_childNodes.end() ) {
		XMLNode* node = *it;	
		XMLNode* newNode = new XMLNode( *node );
		newNode->m_parentNode = this;
		addChildNode( newNode );
		
		it ++;
	}

	m_attrsContainer.initContainer( m_attrs );
	m_childNodesContainer.initContainer( m_childNodes );
}

XMLNode::~XMLNode()
{
	clearChildNodes();
}

XMLAttr* XMLNode::getAttrByName( const String& name )
{
	XMLAttr* result = NULL;
	std::vector<XMLAttr>::iterator it = m_attrs.begin();
	while ( it != m_attrs.end() ){
		if ( name == (*it).getName() ) {
			result = &(*it);
			break;
		}
		it ++;
	}
	return result;
}

XMLAttr* XMLNode::getAttrByIndex( const long& index )
{
	XMLAttr* result = NULL;
	if ( index < m_attrs.size() ) {
		result = &m_attrs[index];
	}
	return result;
}

void XMLNode::removeNode( XMLNode* node )
{
	std::vector<XMLNode*>::iterator found = std::find( m_childNodes.begin(), m_childNodes.end(), node );
	if ( found != m_childNodes.end() ){
		m_childNodes.erase( found );
	}
}

XMLNode* XMLNode::getNodeByName( const String& name )
{
	XMLNode* result = NULL;
	
	std::vector<XMLNode*>::iterator it = m_childNodes.begin();
	while ( it != m_childNodes.end() ) {
		XMLNode* node = *it;
		if ( node->getName() == name ) {
			result = node;
			break;
		}
		it ++;
	}

	return result;
}

XMLNode* XMLNode::getNodeByIndex( const long& index )
{
	XMLNode* result = NULL;
	if ( (index >= 0) && (index < m_childNodes.size()) ) {
		result = m_childNodes[index];
	}

	return result;
}

void XMLNode::clearChildNodes()
{
	std::vector<XMLNode*>::iterator it = m_childNodes.begin();
	while ( it != m_childNodes.end() ) {
		XMLNode* node = *it;
		delete node;
		node = NULL;
		it ++;
	}
}

long XMLNode::getDepth()
{
	long result = 0;

	XMLNode* parent = getParentNode();
	while ( NULL != parent ) {
		result ++;
		parent = parent->getParentNode();
	}
		
	return result;
}

String XMLNode::toString()
{
	String result;

	String tab;
	int tabsize = getDepth();
	for ( int i=0;i<tabsize;i++) {
		tab += "\t";
	}
	String nodeString = tab + "<" + getName() + " ";
	result += nodeString;

	std::vector<XMLAttr>::iterator attrIt = m_attrs.begin();
	while ( attrIt != m_attrs.end() ){
		XMLAttr* attr = &(*attrIt);
		result += attr->toString();
		attrIt ++;
	}
	
	if ( true == m_childNodes.empty() ) {
		nodeString = "/>\n";
		result += nodeString;
	}
	else {
		nodeString = ">\n";
		result += nodeString;		

		std::vector<XMLNode*>::iterator nodeIt = m_childNodes.begin();
		while ( nodeIt != m_childNodes.end() ) {
			XMLNode* node = *nodeIt;
			result += node->toString();	
			nodeIt ++;
		}
		nodeString = tab + "</" + getName() + ">\n";
		result += nodeString;
	}

	return result;
}





XMLParser::XMLParser()
{

	m_parsedNodesContainer.initContainer( m_parsedNodes );
	m_currentNode = NULL;
}

XMLParser::~XMLParser()
{
	clearNodes();
}

Enumerator<XMLNode*>* XMLParser::getParsedNodes()
{
	return m_parsedNodesContainer.getEnumerator();
}

void XMLParser::clearNodes()
{
	std::vector<XMLNode*>::iterator it = m_parsedNodes.begin();
	if ( it != m_parsedNodes.end() ) {
		// the first node is the root, delete it, and all the children go as well
		XMLNode* node = *it;
		delete node;
		node = NULL;		
	}
	m_parsedNodes.clear();
}

void XMLParser::parse( const String& xmlString ) 
{
	m_currentNode = NULL;
	clearNodes();
	if ( ! xmlString.empty() ) {
		m_sourcePtr = xmlString.c_str();
		m_xmlBufferStart = m_sourcePtr;
		m_sourceSize = xmlString.size();
		
		while ( nextNode() ) {
			
		}
	}
}


bool XMLParser::nextNode() 
{		
	if ( m_sourceSize <= (m_sourcePtr - m_xmlBufferStart) ) {
		return false;
	}
	
	const VCFChar* P = m_sourcePtr;
	const VCFChar* tokenStart;
	while ( (*P != 0) && ((' ' == *P) || (13 == *P) || (10 == *P) || (9 == *P)) ) {
		P++;
	}
	
	m_tokenPtr = P;
	
	switch( *P ) {

		case XMLParser::TagOpen : {
			P++;
			tokenStart = P;
			//check for comments				
			if ( *P == XMLParser::TagComment ) {
				String commentTag;
				commentTag.append( P, 3 );	 
				if ( commentTag == "!--" ) {
					P += 3;
					const VCFChar* endComments = parseComments( P );
					P = endComments;
					P++;
					m_sourcePtr = P;
					return true;
				}
				else {
					return false; //invalid XML
				}
			}
			else {
				
				while ( (*P != XMLParser::TagClose) && (*P != 0) ) {
					P++;
				}
				
				//check for end tag
				const VCFChar* endTag = P;
				endTag--;
				bool endTagFound = false;
				if ( *endTag == XMLParser::TagEnd ) {
					endTagFound = true;
					P --; //back up our position
				}
				
				if ( *tokenStart != XMLParser::TagEnd ) {
					//parse the node for attributes
					
					XMLNode* node = new XMLNode("", m_currentNode ); 

					m_parsedNodes.push_back( node );
					m_currentNode = node;
					parseNode( tokenStart, P );				
				}
				//skip past the closing node
				P++; 
				if ( true == endTagFound ) {
					P++; 
					m_sourcePtr = P;
					if ( NULL != m_currentNode ) {
						m_currentNode = m_currentNode->getParentNode();
					}
					return true;
				}
				else {
					if ( *tokenStart == XMLParser::TagEnd ) {
						m_sourcePtr = P;
						if ( NULL != m_currentNode ) {
							m_currentNode = m_currentNode->getParentNode();
						}
						return true;
					}
				}
			}
		}
		break;

		default : {
			m_tokenString = "";
			//check for character data
			while ( (*P != '<') && ( (P - m_xmlBufferStart ) < m_sourceSize) ) {
				P++;
			}

			m_tokenString.append( m_tokenPtr, P - m_tokenPtr );
			if ( NULL != m_currentNode ) {
				m_currentNode->setCDATA( m_tokenString );
			//	XMLParserEvent event( this, m_currentNode );
			//	fireOnNodeCDATAFound( &event );
			}
		}
		break;

	}
	
	m_sourcePtr = P;
	return m_sourceSize > ( m_sourcePtr - m_xmlBufferStart );
}

const VCFChar* XMLParser::parseComments( const VCFChar* commentPtrStart ) 
{
	const VCFChar* result = NULL;
	bool commentsFinished = false;
	while ( (false == commentsFinished) && (m_sourceSize > ( commentPtrStart - m_xmlBufferStart )) ) {
		switch ( *commentPtrStart ) {
			case '-' : {
				const VCFChar* tmp = commentPtrStart;
				tmp++;
				if ( *tmp == '-' ) {
					tmp ++;
					if ( *tmp == XMLParser::TagClose ) {
						//poof - Elvis has left the building ! comments are finished
						commentPtrStart = tmp;
						commentsFinished = true;
					}
				}
			}
			break;
		}
		commentPtrStart++;
	}

	result = commentPtrStart;

	return result;
}

void XMLParser::parseNode( const VCFChar* nodePtrStart, const VCFChar* nodePtrEnd ) 
{				
	const VCFChar* P = nodePtrStart;
	
	while ( (*P != ' ') && (P < nodePtrEnd)  ) {
		P++;
	}
	
	String s;	
	s.append( nodePtrStart, P - nodePtrStart );
	m_currentNode->setName( s );	

	while ( (*P == ' ') && (P < nodePtrEnd)  ) {
		P++;
	}

	parseAttrs( P, nodePtrEnd );

//	XMLParserEvent event( this, m_currentNode );
//	fireOnNodeFound( &event );
}

void XMLParser::parseAttrs( const VCFChar* attrPtrStart, const VCFChar* attrPtrEnd ) 
{
	m_currentNode->clearAttrs();

	const VCFChar* P = attrPtrStart;

	bool nextAttr = P < attrPtrEnd;
	while ( true == nextAttr ) {
		const VCFChar* nameStart = P;
		while ( ((' ' != *P) || (13 != *P) || (10 != *P) || (9 != *P)) && (*P != XMLParser::TagEquals) && (P < attrPtrEnd)  ) {
		//while ( (*P != ' ') && (*P != XMLParser::TagEquals) && (P < attrPtrEnd)  ) {
			P++;
		}
		String name;
		String value;
		name.append( nameStart, P - nameStart );

		bool assignmentOperatorFound = false;
		switch ( *P ) {
			case XMLParser::TagEquals : {
				P++;
				assignmentOperatorFound = true;
			}
			break;

			case 9 : case ' ' : case 10 : case 13: {
				while ( ((' ' == *P) || (13 == *P) || (10 == *P) || (9 == *P)) && (P < attrPtrEnd)  ) {
					P++;
				}
				if ( *P == XMLParser::TagEquals ) {
					P++;	
				}
				assignmentOperatorFound = true;
			}
			break;
		}

		if ( true == assignmentOperatorFound ) {				
			//goto the first quote
			while ( (*P != XMLParser::TagQuote) && (P < attrPtrEnd)  ) {
				P++;
			}
			if ( *P != XMLParser::TagQuote ) {
				throw RuntimeException( "Malformed XML Attribute - string literal expected, but no beginning quote (\") found." );	
			}
			P++;
			const VCFChar* valueStart = P;

			//goto end quote
			while ( (*P != XMLParser::TagQuote) && (P < attrPtrEnd)  ) {
				P++;
			}

			if ( *P != XMLParser::TagQuote ) {
				throw RuntimeException( "Malformed XML Attribute - string literal expected, but no beginning quote (\") found." );	
			}

			value.append( valueStart, P - valueStart );

			m_currentNode->addAttr( XMLAttr(name,value,m_currentNode) );

			P++;

			//get rid of the white space
			while ( ((' ' == *P) || (13 == *P) || (10 == *P) || (9 == *P)) && (P < attrPtrEnd)  ) {
			//while ( (*P == ' ') && (P < attrPtrEnd)  ) {
				P++;
			}
		}
		else {
			throw RuntimeException( "Malformed XML Attribute" );
		}			
		
		nextAttr = P < attrPtrEnd;
	}
}

⌨️ 快捷键说明

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