【问题标题】:Algorithm to print CSS from an HTML document tree从 HTML 文档树中打印 CSS 的算法
【发布时间】:2014-12-09 02:58:49
【问题描述】:

现在我正在尝试创建一个递归函数,该函数接受一个 HTML 文档树并返回一个表示格式化 CSS 的字符串,该字符串仅使用子 (>) 运算符。我会进一步解释它,也许你可以在我遇到困难的地方帮助我。至少请给我一些提示或想法。

所以我们的想法是从

                  body
               /       \
             div        div
            /   \    /   \  \
           h1   p   p    ul  div
                        / \
                       li  li 

div
    div > h1
    div > p
    div > p
    div > ul
        div > ul > li
        div > ul > li
    div > div

或者,如果你愿意,

"div\n\t div > h1\n\tdiv > p\n\tdiv > p\n\tdiv > ul\n\t\tdiv > ul > li\n\t\tdiv > ul > li\n\tdiv > div"

我已经有一个获取body 和从中生长的树的过程。我需要的 3 个函数是名为 XMLNode 的对象的成员

  1. getChildNode(int k) 返回XMLNode 对象,它是kth 子对象。如果不存在,则返回的对象具有属性
  2. isEmpty()
  3. getName() 将节点的名称作为类字符串对象返回,该对象可以转换为字符串。

所以我尝试编写一个可以满足我需要的过程是调用

std::cout << tree2CSS(bodyNode);

函数tree2CSS的实现方式如下

std::string tree2CSS(XMLNode & rootNode, unsigned depth = 0)
{
    int i = 1;
    XMLNode childNode = rootNode.getChildNode(i);
    std::string accumCSS;
    while (!childNode.isEmpty())
    {
        std::string tabs(depth, '\t');
        accumCSS.append("\n" + tabs);
        if (depth > 0) accumCSS.append(" > ");
        accumCSS.append((std::string)childNode.getName() + tree2CSS(childNode, depth + 1));
        childNode = rootNode.getChildNode(++i);
    }
    return accumCSS;
}

问题是,该程序不起作用,我不知道为什么。谁能帮帮我?

【问题讨论】:

  • 您需要遍历该函数并了解它到底在哪里不起作用。顺便问一下,您确定您正在解析 XHTML 文件,而不是带有非 XML 标记的简单 HTML 文件吗?
  • “不工作”是什么意思?程序崩溃了吗?它会返回垃圾吗?它会终止吗?

标签: html c++ css algorithm tree


【解决方案1】:

您想打印每个元素的完整祖先,因此您必须以某种方式跟踪所有父母,而不仅仅是深度。

我认为对于循环外的每个元素最好处理一次打印,并且循环仅用于访问孩子。

这是一个替代实现:

std::string tree2CSS_(XMLNode& rootNode, std::vector<std::string>& pred)
{
    std::string accumCSS(pred.size(), '\t');
    std::string name = rootNode.getName();

    for (size_t i = 0; i < pred.size(); ++i) {
        accumCSS += pred[i] + " > ";
    }
    accumCSS += name + "\n";

    size_t i = 0;
    XMLNode& childNode = rootNode.getChildNode(i);

    pred.push_back(name);
    while (!childNode.isEmpty()) {
        accumCSS.append(tree2CSS_(childNode, pred));
        childNode = rootNode.getChildNode(++i);
    }
    pred.pop_back();

    return accumCSS;
}

std::string tree2CSS(XMLNode& rootNode)
{ 
    std::vector<std::string> pred;
    return tree2CSS_(rootNode, pred);
}

我在这里使用了一个包含前面字符串的向量,它的大小当然是递归深度。实现分为前端函数,提供向量,递归实现。

此实现打印正文节点并将正文添加到所有 CSS 声明符。如果要跳过最顶层的节点,请在前端函数中遍历 body 的子节点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 2015-11-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多