📄 xmlparser.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 + -