Skip to content

Commit

Permalink
添加xml 解析
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaominghe2014 committed Jun 13, 2023
1 parent 2681164 commit 608e4d4
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 5 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ std::string sgfStr ="(;SZ[19]AP[MultiGo:3.6.0]AB[pb][pc][oc][od][ne][nf][og][pg]
auto f = J.charPoly(lambda);
std::cout << "charPoly(" << lambda << ") = " << std::endl<< f << std::endl;
// 使用牛顿迭代法求解矩阵 A 的特征值
// 使用牛顿迭代法求解矩阵 J 的特征值
double epsilon = 1e-6;
int max_iterations = 100;
std::vector<double> eigenvalues_newton = J.eigenvaluesNewton(epsilon, max_iterations);
Expand All @@ -310,7 +310,7 @@ std::string sgfStr ="(;SZ[19]AP[MultiGo:3.6.0]AB[pb][pc][oc][od][ne][nf][og][pg]
}
std::cout << std::endl;
// 使用二分法求解矩阵 A 的特征值
// 使用二分法求解矩阵 J 的特征值
double left = -10;
double right = 10;
std::vector<double> eigenvalues_binary_search = J.eigenvaluesBinarySearch(left, right, epsilon);
Expand All @@ -325,7 +325,7 @@ std::string sgfStr ="(;SZ[19]AP[MultiGo:3.6.0]AB[pb][pc][oc][od][ne][nf][og][pg]
<h4 id='LightsOutPuzzle'>LightsOutPuzzle solover</h4>

点灯游戏的解决方案,
点灯游戏网页例子可以参考:https://github.com/xiaominghe2014/FlipGame
点灯游戏网页例子可以参考:https://xiaominghe2014.github.io/game/flipGame.html

```C++

Expand Down
35 changes: 35 additions & 0 deletions include/parser/xml.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// xml.h
// com.xm.xlib
//
// Created by xiaominghe2014@gmail.com on 2023/6/13.
//

#ifndef xml_h
#define xml_h
#include <string>
#include <vector>

namespace xlib {
struct XMLNode {
std::string name;
std::string value;
std::vector<std::pair<std::string, std::string>> attributes;
std::vector<XMLNode*> children;
};
class XMLParser {
public:
XMLParser();
~XMLParser();
XMLNode* parse(const std::string& xmlStr);
private:
void trim(std::string& str);
XMLNode* parseNode(const std::string& line);
void deleteNode(XMLNode* node);
XMLNode* rootNode;
};

std::string nodeToString(xlib::XMLNode* node);
}

#endif /* xml_h */
1 change: 1 addition & 0 deletions include/xlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@
#include "parser/json.h"
#include "parser/YamlParser.h"
#include "parser/SgfParser.h"
#include "parser/xml.h"
#include "math/math.h"
#endif /* xlib_h */
38 changes: 36 additions & 2 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ void testMatrix(){
auto f = J.charPoly(lambda);
std::cout << "charPoly(" << lambda << ") = " << std::endl<< f << std::endl;

// 使用牛顿迭代法求解矩阵 A 的特征值
// 使用牛顿迭代法求解矩阵 J 的特征值
double epsilon = 1e-6;
int max_iterations = 100;
std::vector<double> eigenvalues_newton = J.eigenvaluesNewton(epsilon, max_iterations);
Expand All @@ -439,7 +439,7 @@ void testMatrix(){
}
std::cout << std::endl;

// 使用二分法求解矩阵 A 的特征值
// 使用二分法求解矩阵 J 的特征值
double left = -10;
double right = 10;
std::vector<double> eigenvalues_binary_search = J.eigenvaluesBinarySearch(left, right, epsilon);
Expand Down Expand Up @@ -499,6 +499,39 @@ void testSolveLightsOutPuzzle(){
*/
}

void testXML(){
std::string xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<bookstore>\n"
" <book category=\"COOKING\">\n"
" <title lang=\"en\">Everyday Italian</title>\n"
" <author>Giada De Laurentiis</author>\n"
" <year>2005</year>\n"
" <price>30.00</price>\n"
" </book>\n"
" <book category=\"CHILDREN\">\n"
" <title lang=\"en\">Harry Potter</title>\n"
" <author>J.K. Rowling</author>\n"
" <year>2005</year>\n"
" <price>29.99</price>\n"
" </book>\n"
" <book category=\"WEB\">\n"
" <title lang=\"en\">Learning XML</title>\n"
" <author>Erik T. Ray</author>\n"
" <year>2003</year>\n"
" <price>39.95</price>\n"
" </book>\n"
"</bookstore>";
xlib::XMLParser parser;
xlib::XMLNode* rootNode = parser.parse(xmlStr);
if (rootNode != nullptr) {
std::cout << "XML parsing successful!" << std::endl;
std::string nodeStr = nodeToString(rootNode);
std::cout << nodeStr << std::endl;
} else {
std::cout << "XML parsing failed!" << std::endl;
}
}

int main(int argc, char* argv[])
{
setLog();
Expand All @@ -512,6 +545,7 @@ int main(int argc, char* argv[])
testSgf();
// testSerializer();
testJson();
testXML();
testThreadPool();
testSHA();
testUtf8();
Expand Down
142 changes: 142 additions & 0 deletions src/parser/xml.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
//
// xml.cpp
// com.xm.xlib
//
// Created by xiaominghe2014@gmail.com on 2023/6/13.
//

#include "parser/xml.h"
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stack>

namespace xlib {

XMLParser::XMLParser():rootNode(nullptr) {}
XMLParser::~XMLParser() {
if (rootNode != nullptr) {
deleteNode(rootNode);
}
}

XMLNode* XMLParser::parse(const std::string& xmlStr) {
std::istringstream stream(xmlStr);
std::stack<XMLNode*> nodeStack;
if (rootNode != nullptr) {
deleteNode(rootNode);
}
rootNode = nullptr;
std::string line;
while (getline(stream, line)) {
trim(line);
if (line.empty()) {
continue;
}

if (line[0] == '<') {
if (line[1] == '/') {
nodeStack.pop();
} else {
XMLNode* node = parseNode(line);
if (nodeStack.empty()) {
rootNode = node;
} else {
nodeStack.top()->children.push_back(node);
}
nodeStack.push(node);
}
} else {
if (!nodeStack.empty()) {
nodeStack.top()->value = line;
}
}
}
return rootNode;
}

void XMLParser::trim(std::string& str) {
size_t start = str.find_first_not_of(" \t\r\n");
if (start != std::string::npos) {
str = str.substr(start);
}
size_t end = str.find_last_not_of(" \t\r\n");
if (end != std::string::npos) {
str = str.substr(0, end + 1);
}
}

XMLNode* XMLParser::parseNode(const std::string& line) {
XMLNode* node = new XMLNode();
size_t pos = line.find_first_of(" \t\r\n>");
if (pos == std::string::npos) {
std::cerr << "Invalid node: " << line << std::endl;
delete node;
return nullptr;
}
node->name = line.substr(1, pos - 1);

// Get node value
size_t valueStart = line.find_first_of(">");
if (valueStart != std::string::npos) {
size_t valueEnd = line.find_last_of("<");
if (valueEnd != std::string::npos) {
node->value = line.substr(valueStart + 1, valueEnd - valueStart - 1);
}
}

size_t len = line.length();
while (pos < len) {
size_t keyStart = line.find_first_not_of(" \t\r\n", pos);
if (keyStart == std::string::npos) {
break;
}
if (line[keyStart] == '/') {
break;
}
size_t keyEnd = line.find_first_of(" \t\r\n=", keyStart);
if (keyEnd == std::string::npos) {
break;
}
size_t valueStart = line.find_first_of("=", keyEnd);
if (valueStart == std::string::npos) {
break;
}
valueStart = line.find_first_not_of(" \t\r\n", valueStart + 1);
if (valueStart == std::string::npos) {
break;
}
char quote = line[valueStart];
if (quote != '\'' && quote != '\"') {
break;
}
size_t valueEnd = line.find(quote, valueStart + 1);
if (valueEnd == std::string::npos) {
break;
}
node->attributes.push_back(make_pair(line.substr(keyStart, keyEnd - keyStart), line.substr(valueStart + 1, valueEnd - valueStart - 1)));
pos = valueEnd + 1;
}
return node;
}

std::string nodeToString(xlib::XMLNode* node) {
std::stringstream ss;
ss<<node->name<<"="<<node->value<<"\n";
for (auto& attribute : node->attributes) {
ss << node->name << "." <<attribute.first << " = " << attribute.second << "\n";
}
for (auto& child : node->children) {
ss << nodeToString(child);
}
return ss.str();
}

void XMLParser::deleteNode(XMLNode* node) {
for (auto& child : node->children) {
deleteNode(child);
}
delete node;
}
}

0 comments on commit 608e4d4

Please sign in to comment.