本段代码通过ACEXML来解析一个XML文件,并且生成了一棵树,树的存储采用孩子兄弟存储的方法。
ACEd.lib
ACEXMLd.lib
ACEXML_Parserd.lib
iphlpapi.lib
CTree
- #pragma once
- #include "string"
- using namespace std;
- class CTree
- {
- public:
- typedef enum{LEAF = 0x00,NOTLEAF = 0x01} ATTRIBUTE;
- public:
- CTree(void);
- CTree(ATTRIBUTE attribute,string value);
- ~CTree(void);
- private:
- ATTRIBUTE m_attribute;
- string m_value;
- CTree* m_left;
- CTree* m_right;
- public:
- void addnode(CTree* children);
- void output(int indent);
- ATTRIBUTE getattribute();
- string getvalue();
- CTree* getleft();
- CTree* getright();
- int getchildnumber();
- CTree* getfirstchild();
- CTree* getnextchild();
- CTree* getchild(int index);
- void destroy();
- };
- #include "Tree.h"
- CTree::CTree(void)
- {
- m_attribute = NOTLEAF;
- m_value = "";
- m_left = NULL;
- m_right = NULL;
- }
- CTree::CTree(ATTRIBUTE attribute,string value)
- {
- m_attribute = attribute;
- m_value = value;
- m_left = NULL;
- m_right = NULL;
- }
- CTree::~CTree(void)
- {
- printf("destroy value=%s\n",m_value.c_str());
- }
- CTree::ATTRIBUTE CTree::getattribute()
- {
- return m_attribute;
- }
- CTree* CTree::getleft()
- {
- return m_left;
- }
- CTree* CTree::getright()
- {
- return m_right;
- }
- string CTree::getvalue()
- {
- return m_value;
- }
- void CTree::destroy()
- {
- if (m_left != NULL)
- {
- m_left->destroy();
- }
- if (m_right != NULL)
- {
- m_right->destroy();
- }
- delete this;
- }
- void CTree::addnode(CTree* child)
- {
- if (m_left == NULL)
- {
- m_left = child;
- }
- else
- {
- CTree* ptemp = m_left;
- while(ptemp->m_right != NULL)
- {
- ptemp = ptemp->m_right;
- }
- ptemp->m_right = child;
- }
- }
- void CTree::output(int indent)
- {
- //printf("value=%s attri=%c this=%08X left=%08X right=%08X\n",m_value.c_str(),((m_attribute == LEAF) ? 'C' : 'P'),this,m_left,m_right);
- //printf("%s(deep=%d)\n",indent);
- printf("%s\n",m_value.c_str());
- if (m_left != NULL)
- {
- indent++;
- for(int i=0; i<indent; i++)
- {
- printf("|____");
- }
- m_left->output(indent);
- indent--;
- }
- if (m_right != NULL)
- {
- for(int i = 0; i < indent; i++)
- {
- printf("|____");
- }
- m_right->output(indent);
- }
- }
- int CTree::getchildnumber()
- {
- int number = 0;
- if (m_left == NULL)
- {
- return number;
- }
- else
- {
- number++;
- CTree* temp = m_left;
- while(temp->m_right != NULL)
- {
- number++;
- temp = temp->m_right;
- }
- }
- return number;
- }
- CTree* CTree::getfirstchild()
- {
- return m_left;
- }
- CTree* CTree::getnextchild()
- {
- return m_right;
- }
- CTree* CTree::getchild(int index)
- {
- CTree* temp = NULL;
- bool find = false;
- int count = 1;
- if (index == 1)
- {
- find = true;
- temp = m_left;
- }
- else
- {
- temp = m_left;
- while(temp->m_right != NULL)
- {
- count++;
- if (count == index)
- {
- find = true;
- break;
- }
- temp = temp->m_right;
- }
- }
- if (find)
- {
- return temp;
- }
- else
- {
- temp = NULL;
- return temp;
- }
- }
CStack
- #pragma once
- #include "Stack"
- class CTree;
- using namespace std;
- typedef stack<CTree*> STACK;
- class CStack
- {
- public:
- CStack(void);
- ~CStack(void);
- private:
- STACK m_stack;
- public:
- void push(CTree* node);
- CTree* pop();
- CTree* get();
- int size();
- bool empty();
- };
- #include "Stack.h"
- CStack::CStack(void)
- {
- }
- CStack::~CStack(void)
- {
- }
- void CStack:: push(CTree* node)
- {
- m_stack.push(node);
- }
- CTree* CStack::pop()
- {
- CTree* node = NULL;
- if (!empty())
- {
- node = get();
- m_stack.pop();
- }
- return node;
- }
- CTree* CStack::get()
- {
- CTree* node = NULL;
- if (!empty())
- {
- node = m_stack.top();
- }
- return node;
- }
- int CStack::size()
- {
- return m_stack.size();
- }
- bool CStack::empty()
- {
- return m_stack.empty();
- }
CXMLParse
- #pragma once
- #include "ACEXML/common/DefaultHandler.h"
- #include "string"
- #include "Tree.h"
- #include "Stack.h"
- using namespace std;
- class CXMLParse : public ACEXML_DefaultHandler
- {
- public:
- CXMLParse(ACEXML_Char* fileName);
- virtual ~CXMLParse(void);
- public:
- // Methods inherited from ACEXML_ContentHandler.
- /*
- * Receive notification of character data.
- */
- virtual void characters (const ACEXML_Char *ch,size_t start,size_t length);
- /*
- * Receive notification of the end of a document.
- */
- virtual void endDocument (void);
- /*
- * Receive notification of the end of an element.
- */
- virtual void endElement (const ACEXML_Char *namespaceURI,const ACEXML_Char *localName,const ACEXML_Char *qName);
- /*
- * End the scope of a prefix-URI mapping.
- */
- virtual void endPrefixMapping (const ACEXML_Char *prefix);
- /*
- * Receive notification of ignorable whitespace in element content.
- */
- virtual void ignorableWhitespace (const ACEXML_Char *ch,int start,int length);
- /*
- * Receive notification of a processing instruction.
- */
- virtual void processingInstruction (const ACEXML_Char *target,const ACEXML_Char *data);
- /*
- * Receive an object for locating the origin of SAX document events.
- */
- virtual void setDocumentLocator (ACEXML_Locator *locator) ;
- /*
- * Receive notification of a skipped entity.
- */
- virtual void skippedEntity (const ACEXML_Char *name);
- /*
- * Receive notification of the beginning of a document.
- */
- virtual void startDocument (void);
- /*
- * Receive notification of the beginning of an element.
- */
- virtual void startElement (const ACEXML_Char *namespaceURI,const ACEXML_Char *qName,ACEXML_Attributes *atts);
- /*
- * Begin the scope of a prefix-URI Namespace mapping.
- */
- virtual void startPrefixMapping (const ACEXML_Char *prefix,const ACEXML_Char *uri);
- // *** Methods inherit from ACEXML_DTDHandler.
- /*
- * Receive notification of a notation declaration event.
- */
- virtual void notationDecl (const ACEXML_Char *name,const ACEXML_Char *publicId,const ACEXML_Char *systemId);
- /*
- * Receive notification of an unparsed entity declaration event.
- */
- virtual void unparsedEntityDecl (const ACEXML_Char *name,const ACEXML_Char *systemId,const ACEXML_Char *notationName);
- // Methods inherit from ACEXML_EnitityResolver.
- /*
- * Allow the application to resolve external entities.
- */
- virtual ACEXML_InputSource *resolveEntity (const ACEXML_Char *publicId,const ACEXML_Char *systemId);
- // Methods inherit from ACEXML_ErrorHandler.
- /*
- * Receive notification of a recoverable error.
- */
- virtual void error (ACEXML_SAXParseException &exception);
- /*
- * Receive notification of a non-recoverable error.
- */
- virtual void fatalError (ACEXML_SAXParseException &exception);
- /*
- * Receive notification of a warning.
- */
- virtual void warning (ACEXML_SAXParseException &exception);
- private:
- ACEXML_Char* fileName_;
- ACEXML_Locator* locator_;
- private:
- CTree *m_ptree;
- CStack m_stack;
- string m_value;
- };
- #include "XMLParse.h"
- #include "ace/ACE.h"
- #include "ace/Log_Msg.h"
- CXMLParse::CXMLParse (ACEXML_Char* fileName) : fileName_(ACE::strnew(fileName))
- {
- m_ptree = NULL;
- m_value = "";
- }
- CXMLParse::~CXMLParse (void)
- {
- delete[] this->fileName_;
- if (m_ptree != NULL)
- {
- m_ptree->destroy();
- }
- }
- void CXMLParse::characters(const ACEXML_Char *cdata,size_t length)
- {
- m_value = string(cdata);
- }
- void CXMLParse::startElement(const ACEXML_Char *uri,const ACEXML_Char *name,ACEXML_Attributes *alist)
- {
- CTree* node = new CTree(CTree::NOTLEAF,name);
- m_stack.push(node);
- }
- void CXMLParse::endElement(const ACEXML_Char *uri,const ACEXML_Char *qName)
- {
- CTree* node = m_stack.get();
- if (node == NULL) return;
- if (node->getleft() == NULL && node->getright() == NULL)//如果栈顶的元素左右没有孩子,说明需要插入节点
- {
- //生成叶子节点
- CTree* newnode = new CTree(CTree::LEAF,m_value);
- //叶子节点的父亲节点出栈
- node = m_stack.pop();
- //设置叶子节点和父亲节点的关系
- node->addnode(newnode);
- CTree* parentnode = m_stack.get();
- if (parentnode == NULL) return;
- parentnode->addnode(node);//记录相互关系,但不用出栈
- }
- else////如果栈顶的元素左右有孩子,说明仅仅需要修改指针关系
- {
- CTree* newnode = m_stack.pop();
- if (m_stack.empty())
- {
- m_ptree = newnode;
- }
- else
- {
- CTree* node = m_stack.get();
- node->addnode(newnode);
- }
- }
- }
- void CXMLParse::endDocument(void)
- {
- //test for display tree
- m_ptree->output(0);
- //test for get children number
- printf("*********************************************\n");
- printf("childnumber = %d\n",m_ptree->getchildnumber());
- printf("*********************************************\n");
- //test for scan a parent's all children
- CTree* node = m_ptree->getfirstchild();
- while(node != NULL)
- {
- printf("value=%s\n",node->getvalue().c_str());
- node = node->getnextchild();
- }
- //test for scan a parent's children
- printf("*********************************************\n");
- for(int i = 0; i < m_ptree->getchildnumber(); i++)
- {
- CTree* node = m_ptree->getchild(i + 1);
- if (node != NULL)
- {
- printf("value=%s\n",node->getvalue().c_str());
- }
- }
- }
- void CXMLParse::endPrefixMapping (const ACEXML_Char *prefix)
- {
- }
- void CXMLParse::ignorableWhitespace(const ACEXML_Char *,int,int)
- {
- }
- void CXMLParse::processingInstruction(const ACEXML_Char *target,const ACEXML_Char *data)
- {
- }
- void CXMLParse::setDocumentLocator(ACEXML_Locator * locator)
- {
- this->locator_ = locator;
- }
- void CXMLParse::skippedEntity(const ACEXML_Char *name)
- {
- }
- void CXMLParse::startDocument(void)
- {
- }
- void CXMLParse::startPrefixMapping(const ACEXML_Char * prefix,const ACEXML_Char * uri)
- {
- }
- void CXMLParse::notationDecl(const ACEXML_Char *name,const ACEXML_Char *publicID,const ACEXML_Char *systemID)
- {
- }
- void CXMLParse::unparsedEntityDecl(const ACEXML_Char *name,const ACEXML_Char *systemID,const ACEXML_Char *notationName)
- {
- }
- ACEXML_InputSource * CXMLParse::resolveEntity (const ACEXML_Char *,const ACEXML_Char *)
- {
- return 0;
- }
- void CXMLParse::error(ACEXML_SAXParseException & ex)
- {
- /*ACE_DEBUG((LM_DEBUG,"%s: line: %d col: %d ",(this->locator_->getSystemId() == 0 ? this->fileName_ : this->locator_->getSystemId()),this->locator_->getLineNumber(),this->locator_->getColumnNumber()));
- ex.print();*/
- }
- void CXMLParse::fatalError(ACEXML_SAXParseException& ex)
- {
- /*ACE_DEBUG ((LM_DEBUG,this->locator_->getColumnNumber()));
- ex.print();*/
- }
- void CXMLParse::warning(ACEXML_SAXParseException & ex)
- {
- /*ACE_DEBUG ((LM_DEBUG,this->locator_->getColumnNumber()));
- ex.print();*/
- }
CDecodeXML
- #pragma once
- #include "string"
- using namespace std;
- class CDecodeXML
- {
- public:
- CDecodeXML(void);
- ~CDecodeXML(void);
- public:
- bool decode(string xmlfilename);
- };
- #include "DecodeXML.h"
- #include "ACEXML/common/FileCharStream.h"
- #include "ACEXML/parser/parser/Parser.h"
- #include "XMLParse.h"
- #include "ace/Auto_Ptr.h"
- CDecodeXML::CDecodeXML(void)
- {
- }
- CDecodeXML::~CDecodeXML(void)
- {
- }
- bool CDecodeXML::decode(string xmlfilename)
- {
- int result = true;
- ACEXML_Char* filename = (ACEXML_Char*)xmlfilename.c_str();
- ACEXML_FileCharStream *fstm = 0;
- ACE_NEW_RETURN(fstm,ACEXML_FileCharStream(),!result);
- if (fstm->open(filename) != 0)
- {
- printf("Failed to open XML file: %s\n",filename);
- result = false;
- return result;
- }
- ACEXML_CharStream *stm = fstm;
- CXMLParse *handler = 0;
- ACE_NEW_RETURN(handler,CXMLParse(filename),!result);
- auto_ptr<ACEXML_DefaultHandler> cleanup_handler(handler);
- ACEXML_Parser parser;
- ACEXML_InputSource input(stm);
- parser.setContentHandler(handler);
- parser.setDTDHandler(handler);
- parser.setErrorHandler(handler);
- parser.setEntityResolver(handler);
- try
- {
- parser.parse(&input);
- }
- catch (const ACEXML_SAXException& ex)
- {
- ex.print();
- printf("Exception occurred. Exiting...\n");
- result = false;
- }
- return result;
- }
主函数测试:
- #include "stdafx.h"
- #include "DecodeXML.h"
- int main(int argc,char* argv[])
- {
- CDecodeXML decodexml;
- decodexml.decode("d:\\xml\\1.xml");
- getchar();
- return 0;
- }