我正在JAVA中编写自己的HTML解析器实现。 到目前为止,我已经完成了词法分析器并继续编写解析器。我正在创建DOM树,我想确定我的HTML是否正确构建。
例如,我有 img 标记,这是基于w3 org html syntax的 void 标记
并且它不需要结束标记。
另一方面, body , head 等大部分代码都必须包含其结束标记。
我的问题是:处理此问题的正确方法是什么?
我不需要工具或任何外部网站来判断,我问的是确定的方法。
答案 0 :(得分:2)
这是许多软件公司的典型“求职面试问题”。它是关于检查String(在这种情况下,您的HTML代码)是否与某些字符(在本例中为HTML标记)相平衡。使用Stack解决了这个问题。在处理String时,对于每个开始标记,您将调用“推送”操作。对于每个结束标记,您将调用“弹出”操作。如果在处理结束时堆栈为空(并且在分析期间未发现错误),则将平衡HTML代码。下面的函数检查字符串是否在括号中平衡。
private boolean isBalanced(String s) {
Stack symbolStack = new Stack();
for(int i = 0; i < s.length(); i++) { //Processing the input string ...
char c = s.charAt(i);
if(c == '(') { //If the character is an opening parenthesis --> push
symbolStack.push(c);
}
else if(c == ')') { //If the character is a closing parenthesis ...
if(symbolStack.isEmpty()) { //Error: the stack is empty
return false;
}
else {
char c2 = (char) symbolStack.pop();
if(c2 != '(') { //Error: no opening parenthesis in the stack
return false;
}
}
}
}
if(symbolStack.isEmpty()) { //No error and empty stack --> balanced string
return true;
}
return false;
}
答案 1 :(得分:1)
您正在处理HTML,因此标记集非常有限。如果标记是 void 标记,您可以轻松跟踪。
对于其余的标签,我建议使用以下算法:
获取下一个标签。 (a)如果是开始标记,例如&lt; body&gt; ,只需将其推送到堆栈即可。 (b)如果是结束标记,请转到步骤2。 (c)如果没有剩余的标签需要解析,那么您的HTML就有效了。
逐个从堆栈中弹出标签。 (a)如果在到达当前标记的开头对之前在堆栈上遇到另一个开始标记,那么HTML结构已损坏。 (b)如果您清空堆栈并且仍然没有与当前结束标记的对,那么再次,您的HTML已损坏。 (c)如果遇到当前标签的开启对,则避免出现(a)和(b)情况。转到第1步。
这是一个粗略的伪代码,但我希望你能得到这个想法。如有必要,我可以用Java / C#编写实现。