庞果英雄会——xml字符串文件的解析
发布时间:2020-12-16 06:00:20 所属栏目:百科 来源:网络整理
导读:不知道为什么提交后总是失败, 本机编译通过。 总是使用用例失败。 #include iostream#include string#include listusing namespace std;struct XMLAttribute { string sName; // 名称 string sText; // 内容 XMLAttribute* pNext; // 弟属性 XMLAttribute*
不知道为什么提交后总是失败, 本机编译通过。 总是使用用例失败。 #include <iostream> #include <string> #include <list> using namespace std; struct XMLAttribute { string sName; // 名称 string sText; // 内容 XMLAttribute* pNext; // 弟属性 XMLAttribute* pPre; // 兄属性 }; struct XMLNode { int nFloor; // 层数 int nNum; // 该层第几个节点 int nAttCount; // 属性个数 int nChildCount; // 孩子节点个数 string sName; // 名称 XMLAttribute* pAttList; XMLNode* pParentNode; // 父节点指针 XMLNode* pChildNode; // 孩子节点指针 XMLNode* pPreBrother; // 兄节点指针 XMLNode* pNextBrother; // 弟节点指针 }; void addNodeAttribute(XMLNode* pNode,XMLAttribute* pAtt) { //printf("%s%s","addNodeAttribute start: ",pNode->sName.c_str()); XMLAttribute* pTempAtt = pNode->pAttList; if (!pTempAtt) { pNode->pAttList = pAtt; } else { while (pTempAtt->pNext) { pTempAtt = pTempAtt->pNext; } pTempAtt->pNext = pAtt; pAtt->pPre = pTempAtt; } pNode->nAttCount++; //printf("%s%d","addNodeAttribute end: ",pNode->nAttCount); } void addChildNode(XMLNode* pNode,XMLNode* pChildNode) { //printf("%s%s %s","addChildNode start: ",pNode->sName.c_str(),pChildNode->sName.c_str()); XMLNode* pTempNode = pNode->pChildNode; if (!pTempNode) { pNode->pChildNode = pChildNode; pChildNode->nFloor = pNode->nFloor + 1; pChildNode->nNum = 1; } else { while (pTempNode->pNextBrother) { pTempNode = pTempNode->pNextBrother; } pTempNode->pNextBrother = pChildNode; pChildNode->pPreBrother = pTempNode; pChildNode->nFloor = pNode->nFloor + 1; pChildNode->nNum = pTempNode->nNum + 1; } pChildNode->pParentNode = pNode; pNode->nChildCount++; //printf("%s%d","addChildNode end: ",pNode->nChildCount); } void freeNodeAttributes(XMLNode* pNode) { //printf("%s%s","freeNodeAttributes start: ",pNode->sName.c_str()); XMLAttribute* pTempAtt = pNode->pAttList; // 遍历删除 while (pTempAtt) { XMLAttribute* pDelAtt = pTempAtt; pTempAtt = pTempAtt->pNext; //printf("%s%s %s","free XMLAttribute: ",pDelAtt->sName.c_str(),pDelAtt->sText.c_str()); delete pDelAtt; pNode->nAttCount--; } pNode->pAttList = NULL; //printf("%s","freeNodeAttributes end"); } // 释放节点内存,不释放兄弟节点,只对兄弟节点做双向链接 void freeNode(XMLNode* pNode) { // 首先处理兄弟节点链表,脱离兄弟链表 if (pNode->pNextBrother) { // 存在弟节点 if (pNode->pPreBrother) { // 存在兄节点 pNode->pPreBrother->pNextBrother = pNode->pNextBrother; pNode->pNextBrother->pPreBrother = pNode->pPreBrother; } else if (pNode->pParentNode) { // 存在父节点 pNode->pParentNode->pChildNode = pNode->pNextBrother; } } // 处理父节点 if (pNode->pParentNode) { pNode->pParentNode->nChildCount--; if (pNode->pParentNode->nChildCount == 0) { pNode->pParentNode->pChildNode = NULL; } } pNode->pParentNode = NULL; // 通过栈遍历删除字节点 list<XMLNode*> pNodesList; pNodesList.push_front(pNode); while (pNodesList.size()) { XMLNode* pTempNode = pNodesList.front(); //printf("%s%s%d","cur node: ",pTempNode->sName.c_str(),pTempNode->nChildCount); if (!pTempNode->pChildNode) { // 无子节点出栈操作并删除 // 父节点操作 if (pTempNode->pParentNode) { pTempNode->pParentNode->nChildCount--; if (pTempNode->pParentNode->nChildCount == 0) { pTempNode->pParentNode->pChildNode = NULL; } } pNodesList.pop_front(); // 从栈移除 freeNodeAttributes(pTempNode); //printf("%s%s","free node: ",pTempNode->sName.c_str()); delete pTempNode; pTempNode = NULL; } if (pTempNode) { // 子节点入栈 XMLNode* pChildNode = pTempNode->pChildNode; while (pChildNode) { pNodesList.push_front(pChildNode); pChildNode = pChildNode->pNextBrother; } } } } string trimLeft(string& str) { string tempStr = str; string::size_type nLeftPos = 0; while (str.at(nLeftPos) == ' ' && nLeftPos < str.size()) { nLeftPos++; } tempStr = str.substr(nLeftPos); return tempStr; } string trimRight(string& str) { string tempStr = str; string::size_type nRightPos = str.size() - 1; int nCount = 0; while (str.at(nRightPos) == ' ' && nRightPos > 0) { nRightPos--; nCount++; } if (nCount) { tempStr = str.substr(0,str.size() - nCount); } return tempStr; } string strTrim(string& str) { string tempStr = str; tempStr = trimLeft(tempStr); tempStr = trimRight(tempStr); return tempStr; } enum NodeStatus { NodeError,NodeStart,NodeFinished,AttFinished }; NodeStatus parsingSubstringToNode(string str,XMLNode* pNode) { NodeStatus status = NodeError; //printf("%s%s","parsingSubstringToNode start: ",str.c_str()); if (str.at(0) == '<' && str.at(str.size() - 1) == '>') { if (str.at(1) == '/' && str.at(str.size() - 2) != '/') { status = NodeFinished; pNode->sName = str.substr(2,str.size() - 3); pNode->sName = strTrim(pNode->sName); //printf("%s",pNode->sName.c_str()); } else if (str.at(str.size() - 2) == '/') { status = AttFinished; str = str.substr(1,str.size() - 2); //printf("%s%s","Att: ",str.c_str()); string::size_type nLeftPos = 0; string::size_type nRightPos = str.find("="); // 查找属性 while (nRightPos != string::npos) { //printf("%s",str.c_str()); XMLAttribute* pAtt = new XMLAttribute; pAtt->pNext = NULL; pAtt->pPre = NULL; pAtt->sName = ""; pAtt->sText = ""; addNodeAttribute(pNode,pAtt); pAtt->sName = str.substr(nLeftPos,nRightPos); pAtt->sName = strTrim(pAtt->sName); str = str.substr(nRightPos + 1); nRightPos = str.find("""); if (nRightPos != string::npos) { str = str.substr(nRightPos + 1); nRightPos = str.find("""); if (nRightPos != string::npos) { pAtt->sText = str.substr(nLeftPos,nRightPos); pAtt->sText = strTrim(pAtt->sText); str = str.substr(nRightPos + 1); } } nRightPos = str.find("="); } } else { status = NodeStart; pNode->sName = str.substr(1,str.size() - 2); } } //printf("%s","parsingSubstringToNode end"); return status; } XMLNode* BuildTree(string& in) { XMLNode* pRootNode = NULL; list<XMLNode*> nodeList; string xmlNodeLeft = "<"; string xmlNodeRight = ">"; in = strTrim(in); while (in.size()) { XMLNode* pNode = new XMLNode; pNode->sName = ""; pNode->nAttCount = 0; pNode->nChildCount = 0; pNode->nFloor = 0; pNode->nNum = 0; pNode->pAttList = NULL; pNode->pChildNode = NULL; pNode->pNextBrother = NULL; pNode->pParentNode = NULL; pNode->pPreBrother = NULL; string::size_type nLeftPos = 0; string::size_type nRightPos = in.find(xmlNodeRight); XMLNode* pTempNode = nodeList.front(); if (in.at(nLeftPos) == '<' && nRightPos != string::npos) { string tempStr = in.substr(nLeftPos,nRightPos - nLeftPos + 1); NodeStatus status = parsingSubstringToNode(tempStr,pNode); switch (status) { case NodeStart: { if (nodeList.size() > 0) { addChildNode(pTempNode,pNode); } else { pRootNode = pNode; pRootNode->nFloor = 0; } nodeList.push_front(pNode); break; } case NodeFinished: { if (nodeList.size() > 0) { if (pTempNode->sName != pNode->sName) { freeNode(pRootNode); pRootNode = NULL; return pRootNode; } else { nodeList.pop_front(); //printf("%s%s","NodeFinished: ",pNode->sName.c_str()); freeNode(pNode); //printf("%s","NodeFinished"); } } break; } case AttFinished: { if (nodeList.size() == 0) { freeNode(pRootNode); pRootNode = NULL; return pRootNode; } else { // 赋值当前节点的属性 pTempNode->nAttCount = pNode->nAttCount; pTempNode->pAttList = pNode->pAttList; pNode->nAttCount = 0; pNode->pAttList = NULL; freeNode(pNode); } break; } } if (status == NodeError) { freeNode(pRootNode); pRootNode = NULL; return pRootNode; } if (nRightPos + 1 < in.size()) { in = in.substr(nRightPos + 1); in = trimLeft(in); } else { in = ""; } } else { freeNode(pRootNode); pRootNode = NULL; return pRootNode; } } return pRootNode; } string getTreeString(XMLNode* pNode) { string str = ""; string sNewLine = "rn"; string sTab = "t"; // 输出XML解析字符串 // 通过栈遍历 list<XMLNode*> pNodesList; pNodesList.push_front(pNode); while (pNodesList.size()) { XMLNode* pTempNode = pNodesList.front(); pNodesList.pop_front(); // 输出节点名 for (int i = 0; i < pTempNode->nFloor; i++) { str += sTab; } str += pTempNode->sName; if (pTempNode->nFloor > 0) { char sNum[10]; sprintf(sNum,"%d",pTempNode->nNum); str += " " + string(sNum); } str += sNewLine; // 输出属性 XMLAttribute* pTempAtt = pTempNode->pAttList; while (pTempAtt) { for (int i = 0; i < pTempNode->nFloor + 1; i++) { str += sTab; } str += pTempAtt->sName + ":" + pTempAtt->sText + sNewLine; pTempAtt = pTempAtt->pNext; } // 字节点入栈 XMLNode* pChildNode = pTempNode->pChildNode; // 首先逆序 while (pChildNode && pChildNode->pNextBrother) { pChildNode = pChildNode->pNextBrother; } while (pChildNode) { pNodesList.push_front(pChildNode); pChildNode = pChildNode->pPreBrother; } } return str; } string ParsingXML(string str) { //printf("%s","ParsingXML start"); string result = ""; string in = str; string xmlVersionLeft = "<?"; string xmlVersionRight = "?>"; // 首先查找XML版本并移除 string::size_type nLeftPos = in.find(xmlVersionLeft); string::size_type nRightPos = 0; if (nLeftPos != string::npos) { nRightPos = in.find(xmlVersionRight); if (nRightPos == string::npos) { result = "Invalid XML string."; return result; } else { nRightPos += xmlVersionRight.size(); in = in.substr(nRightPos); } } XMLNode* pRootNode = BuildTree(in); result = getTreeString(pRootNode); // 清理树 freeNode(pRootNode); //printf("%s","ParsingXML end"); return result; } //start 提示:自动阅卷起始唯一标识,请勿删除或增加。 int main() { string in = "<?xml version="1.0" ?><Books><Book><Name = "The C++ Programming Language" Author="Bjarne Stroustrup" /></Book><Book><Name = "Effective C++" Author = "Scott Meyers" /></Book></Books>"; string out = ParsingXML(in); printf("%s",out); return 0; } //end //提示:自动阅卷结束唯一标识,请勿删除或增加。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |