2
\$\begingroup\$

Problem

I need to read custom text input of a sample document object model (DOM) represented in a json format from a file and store it in a struct I've defined as DomNode. I need help on properly navigating these DOM elements from the input file and keeping track of the child node pointers at each level of the dom tree.

The read_dom_hierarchy has a block comment that shows the contents of dom.txt.

I can not use any 3rd party libraries for this problem. Assume dom.txt will always have exactly 18 lines and it's content will not change.

Source

#include <fstream>
#include <iostream>
#include <stack>
#include <string>
#include <sstream>
#include <vector>

struct DomNode
{
    int level;
    std::string tag;
    std::string id;
    std::vector<DomNode*>child;
};

static void read_dom_hierarchy(std::string* dom)
{
    // reading custom input on my local machine, that follows this structure
    /*
        {
            "tag": "div",
            "id": "first",
            "children":
            [
                {
                    "tag": "span",
                    "id": "second",
                    "children":
                    [
                        {
                            "tag": "span",
                            "id": "third"
                        }
                    ]
                }
            ]
        }
    */
    std::ifstream file_stream("dom.txt");
    std::string line;
    int i = 0;
    while (getline(file_stream, line))
    {
        dom[i] = line;
        i++;
    }
}

static void parse_element_data(std::string& s)
{
    s = s.substr(s.find(":") + 2);
    s.erase(s.find(","));
    s.erase(s.find("\""));
}

static void construct_dom_from_text(std::string* dom, DomNode* node, std::stack<std::string> token)
{
    DomNode* current = node;

    int level = 1;
    for (int i = 0; i < 18; i++)
    {
        std::string line = dom[i];
        if (line.find("{") != std::string::npos) 
        {
            token.push(line);
        } 
        else if(line.find("}") != std::string::npos) 
        {
            if (token.top() == "{") {
                token.pop();
                return;
            }
            else {
                token.push(line);
            }
        } 
        if (line.find("[") != std::string::npos) 
        {           
            token.push(line);
            ++level;
        } 
        else if (line.find("]") != std::string::npos) 
        {
            if (token.top() == "[") {
                token.pop();
                --level;
            }
            else {
                token.push(line);
            }
        }

        if (level == 0) { return; }

        // store dom current data
        if (line.find("tag") != std::string::npos) {
            parse_element_data(line);
            current->tag = line;
        }
        else if (line.find("id") != std::string::npos) {
            parse_element_data(line); 
            current->id = line;
        }
        else if (line.find("children") != std::string::npos) {
            current->level = level;
            DomNode* c = new DomNode();
            current->child.push_back(c);
        }
    }
}

int main()
{
    std::string dom[18];
    read_dom_hierarchy(dom);

    DomNode* root = new DomNode();
    std::stack<std::string> token;
    construct_dom_from_text(dom, root, token);
}
\$\endgroup\$
4

Browse other questions tagged or ask your own question.