C++ 使用链接列表实现堆栈类验证xml文件

C++ 使用链接列表实现堆栈类验证xml文件,c++,validation,C++,Validation,使用链接列表实现堆栈类。使用堆栈类验证XML文件。 编写C++程序从命令行读取XML文件,并验证XML匹配的不区分大小写的开始和结束标记。 向所有缺少的相应开始或结束标记提供错误消息,并继续验证所有XML文件 示例以更正XML文档 <Students> <Student> <Name>Tanver</Name> <RollNo>312</RollNo> <student&

使用链接列表实现堆栈类。使用堆栈类验证XML文件。 编写C++程序从命令行读取XML文件,并验证XML匹配的不区分大小写的开始和结束标记。 向所有缺少的相应开始或结束标记提供错误消息,并继续验证所有XML文件

示例以更正XML文档

<Students>
    <Student>
        <Name>Tanver</Name>
        <RollNo>312</RollNo>
    <student>
<students>

坦韦尔
312
不正确的XML文档示例,缺少“head”和“html”结束标记。缺少“name”开始标记

<html>
    <head>
        <title>My first page</title>
        </name>
<body>
    My first page
</body>

我的第一页
我的第一页

我也在训练C++,认为这是一个很好的练习。以下是我的想法:

#include <iostream>
#include <vector>
#include <string>
#include <regex>

using namespace std;

template <typename T>
class Item {
    public:
        T data;
        Item *prev;
        Item(T& data, Item *prev) : data(data), prev(prev) {}
};

template <typename T>
class StackIterator {
    public:
        Item<T> *curr;

        StackIterator(Item<T> *curr) : curr(curr) {}

        T& operator*() { 
            return curr->data;
        }

        StackIterator<T>& operator++() {
            curr = curr->prev; 
            return *this; 
        }

        friend bool operator!=(const StackIterator<T>& l, const StackIterator<T>& r) {
            return l.curr != r.curr;
        }
};

template <typename T>
class Stack {
    typedef StackIterator<T> iterator;

    public:
        Item<T> *last=NULL;

        T& back(void) {
            return last->data;
        }

        void push_back(T d) {
            last = new Item<T>(d, last);
        }

        void pop_back(void) {
            Item<T> *curr = last;
            last = last->prev;
            delete curr;
        }

        ~Stack() {
            while (last) pop_back();
        }

        iterator begin() {
            return iterator(last);
        }

        iterator end() {
            return iterator(NULL);
        }
};

int main() {
    string xml[] = {"<Students>", "<Student>", "<Name>", "Tanver", "</Name>",
        "<RollNo>", "312", "</RollNo>", "</Student>", "</Students>"};

    //string xml[] = {"<html>", "<head>", "<title>", "My first page", "</title>",
    //    "</name>", "<body>", "My first page", "</body>"};

    regex opentag("^<(.*)>$");
    regex closetag("^</(.*)>$");
    smatch m;

    Stack<string> v;
    //vector<string> v;

    for (auto& it : xml) {
        if (regex_search(it, m, closetag)) {
            for (auto& x : m)
                if (x == v.back()) {
                    v.pop_back();
                    cout << "closing " << x << "\n";
                } else {
                    cout << "Tag " << x << " was not opened\n";
                }
        } else if (regex_search(it, m, opentag)) {
            for (auto &x : m) {
                cout << "opening " << x << "\n";
                v.push_back(x);
            }
        } else {
            cout << "data: " << it << "\n";
        }
    }

    for (auto& x : v) {
        cout << "Tag " << x << " was not closed\n";
    }
}
#包括
#包括
#包括
#包括
使用名称空间std;
模板
类项目{
公众:
T数据;
项目*prev;
项目(T&data,项目*prev):数据(data),prev(prev){}
};
模板
类堆栈迭代器{
公众:
项目*货币;
堆栈迭代器(Item*curr):curr(curr){}
T&算子*(){
返回当前->数据;
}
堆栈迭代器和运算符++(){
当前=当前->当前;
归还*这个;
}
友元布尔运算符!=(常量堆栈迭代器&l,常量堆栈迭代器&r){
返回l.curr!=r.curr;
}
};
模板
类堆栈{
typedef堆栈迭代器迭代器;
公众:
Item*last=NULL;
T&back(无效){
返回上次->数据;
}
无效推回(T d){
最后一项=新项目(d,最后一项);
}
void pop_back(void){
项目*当前=最后一个;
最后一次=最后一次->上一次;
删除curr;
}
~Stack(){
当(最后)弹回来时();
}
迭代器begin(){
返回迭代器(最后一个);
}
迭代器结束(){
返回迭代器(NULL);
}
};
int main(){
字符串xml[]={“”,“”,,“Tanver”,“”,
"", "312", "", "", ""};
//字符串xml[]={“”、“”、“”我的第一页、“”、,
//“,”,“我的第一页”,“};
regex opentag(“^$”);
regex closetag(“^$”);
smatch m;
堆栈v;
//向量v;
for(auto&it:xml){
if(正则表达式搜索(it、m、closetag)){
用于(自动和x:m)
如果(x==v.back()){
v、 向后弹出();

这看起来很像家庭作业。如果我们只是给你一个答案,你就学不到多少。如果你有尝试,即使你只尝试解决问题的一小部分,也会更好。然后我们可以给你提示并帮助你。最终结果:你学到了一些东西。@user3397832实际上,除非它是一个省略,否则第一个XML也是不正确的。End标记s代表学生,学生们错过了斜线。