提问人:Madara's Ghost 提问时间:5/5/2012 最后编辑:CommunityMadara's Ghost 更新时间:5/19/2012 访问量:251
DOM 解析器是如何实现的?
How are DOM parsers implemented?
问:
我的经验告诉我,不应该使用 RegExp 来解析 HTML/XML,我完全同意!它
- 混乱
- 不坚固,易折断
- 纯粹的邪恶
他们都说“使用某种 DOM 解析器”,这对我来说很好。但现在我开始好奇了。这些是如何工作的?
我正在搜索 DOMDocument 类源,但找不到它。
这个问题来自这样一个事实,例如,它被认为是使用 RegExp 验证电子邮件的一个很好的替代方案,但当您查看源代码时,您会发现它实际上使用了 RegExp 本身!filter_var()
那么,如果你要在PHP中构建一个DOM解析器呢?您将如何解析 HTML?他们是怎么做到的?
答:
好消息来了,你不需要重新发明轮子。libxml 库用于 PHP 的 DOMDocument 扩展中,其源代码可用。看一看那里我建议。
顺便说一句,正则表达式并不总是错误的,但你需要正确使用它们,否则你会直接进入地狱厨房,成为小猫连环杀手或访问 chutullu 或那个家伙的称呼。因此,我建议阅读以下内容:REX:使用正则表达式的 XML 浅层解析。
但是,如果您做对了所有事情,正则表达式可以为您提供很多解析帮助。只是你应该知道你在做什么。
评论
我认为您应该查看文章浏览器如何工作:现代 Web 浏览器的幕后花絮。这是一本冗长的读物,但非常值得你花时间。具体来说,HTML Parser 部分。
虽然我不能公正地对待这篇文章,但也许粗略的总结会很好,直到他们有时间阅读和消化这部杰作。不过,我必须承认,在这个领域,我是一个经验很少的新手。在专业地为网络开发了大约 10 年之后,浏览器处理和解释我的代码的方式长期以来一直是一个黑匣子。
HTML、XHTML、CSS 或 JavaScript - 任您挑选。他们都有一个语法,以及一个词汇。英语是另一个很好的例子。我们有语法规则,我们希望人们、书籍和其他人遵守这些规则。我们还有一个由名词、动词、形容词等组成的词汇表。
浏览器通过检查文档的语法和词汇来解释文档。当它遇到最终无法理解的项目时,它会让你知道(引发异常等)。你和我在通俗地说也是一样的。
我喜欢 StackOverflow,但如果我能改变一件事,那就是绝对破碎......
请注意,在上面的示例中,您如何立即开始区分单词和单词之间的关系。开头完全有道理,“我喜欢 StackOverflow。然后我们来到“......如果我能改变,“我们立即停下来。“已更改”不属于此处。作者的意思很可能是“改变”。现在词汇是对的,但语法是错误的。过了一会儿,我们遇到了“be be”,这也可能违反了语法规则,再往前走,我们遇到了“absolutamente”这个词,它不是英语词汇的一部分——另一个错误。
将所有这些视为 DOCTYPE。我现在在我的第二台显示器上打开了 XHTML 1.0 Strict Doctype 背后的源代码。在其内部结构中,有如下行:
<!ENTITY % heading "h1|h2|h3|h4|h5|h6">
这将定义标题实体。只要我遵守XHTML的语法,我就可以在我的文档中使用其中任何一个()。但是,如果我试图编造一个,比如说,浏览器会偶然发现词汇是“外国”,并通知我:<h1>Hello World</h1>
H7
“第 7 行,第 8 列:元素”h7“未定义”
也许在解析文档时我们遇到了.我们知道我们现在正在处理一个元素,它有自己的一组词汇,例如 、 等。只要我们知道语言、语法规则等,我们就知道什么时候出了问题。回到 XHTML 1.0 Strict Doctype,我们发现以下内容:<table
table
tbody
tr
<!ELEMENT table
(caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>
<!ELEMENT caption %Inline;>
<!ELEMENT thead (tr)+>
<!ELEMENT tfoot (tr)+>
<!ELEMENT tbody (tr)+>
<!ELEMENT colgroup (col)*>
<!ELEMENT col EMPTY>
<!ELEMENT tr (th|td)+>
<!ELEMENT th %Flow;>
<!ELEMENT td %Flow;>
有了这个参考,我们可以对我们正在解析的任何来源进行运行检查。如果作者写的是 ,而不是 ,我们有一个标准,据此我们可以确定这是错误的。当问题没有得到解决,并且我们无法找到与语法和词汇的某些用法相匹配的规则时,我们会通知作者他们的文档无效。tread
thead
我绝不是在做这个科学正义,但我希望这能起到足够的作用——如果没有更多的话——足以让你自己坐下来阅读作为这个答案开头的文章,也许坐下来研究我们每天遇到的各种 DTD。
评论
filter_var()
filter_var()