gpt4 book ai didi

c - 将简单的 HTML 解析成树

转载 作者:太空狗 更新时间:2023-10-29 17:13:21 26 4
gpt4 key购买 nike

我想问一下将简单的 html 代码解析为像这样的 DOM 节点树的最佳方法是什么:

example tree

以下是我面临的一些限制:

  • HTML 代码只有成对标记,没有属性,我必须忽略空格
  • 标签之间可以有文本,如<p> , <h1> , <a>
  • 我不会使用图书馆

我在考虑正则表达式,但从未尝试过。有什么想法吗?

树中的每个节点都是这个结构:

  typedef struct tag
{
struct tag* parent;
struct tag* nextSibling;
struct tag* previousSibling;
struct tag* firstChild;
struct tag* lastChild;
char* name;
char* text;
}node;

最佳答案

我知道它不是用 C 语言编写的,但该演示文稿可能会给您一些关于如何有效解决问题的意见。

https://web.archive.org/web/20120115060003/http://cuddle.googlecode.com/hg/talk/lex.html#landing-slide

我还根据您的初始要求用 JavaScript(同样不是 C,但希望您也了解 JS)编写了一个非常简单的解析器示例,这意味着它不会解析任何属性并且不会处理自闭合标签和许多其他应该根据 HTML 规范处理的事情。它将生成这种格式的解析树:

{
cn: [{
tag: 'html',
cn: [{
tag: 'body',
cn: [
{ tag: 'h1', cn: ['test'] },
' some text ',
...
]
}]
}]
}

这是代码和 fiddle :http://jsfiddle.net/LUpyZ/3/

请注意,空白不会被忽略,并且会在文本节点中被捕获。

var html = '<html><body><h1>test</h1> some text <div> <p>text</p></div></body></html>';

var parseHTML = (function () {
var nodesStack = [],
i = 0,
len = html.length,
stateFn = parseText,
parseTree = { cn: [] },
alphaNumRx = /\w/,
currentNode = parseTree,
text = '',
tag = '',
newNode;

function parseTag(token) {
if (token === '/') {
return parseCloseTag;
}

i--; //backtrack to first tag character
return parseOpenTag;
}

function parseCloseTag(token) {
if (token === '>') {
if (currentNode.tag !== tag) {
throw 'Wrong closed tag at char ' + i;
}

tag = '';

nodesStack.pop();

currentNode = currentNode.parentNode;

return parseText;
}

assertValidTagNameChar(token);

tag += token;

return parseCloseTag;
}

function parseOpenTag(token) {
if (token === '>') {
currentNode.cn.push(newNode = { tag: tag, parentNode: currentNode, cn: []});
nodesStack.push(currentNode = newNode);

tag = '';

return parseText;
}

assertValidTagNameChar(token);

tag += token;

return parseOpenTag;
}

function parseText(token) {
if (token === '<') {

if (text) {
currentNode.cn.push(text);
text = '';
}

return parseTag;
}

text += token;

return parseText;
}

function assertValidTagNameChar(c) {
if (!alphaNumRx.test(c)) {
throw 'Invalid tag name char at ' + i;
}
}

return function (html) {
for (; i < len; i++) {
stateFn = stateFn(html[i]);
}

if (currentNode = nodesStack.pop()) {
throw 'Unbalanced tags: ' + currentNode.tag + ' is never closed.';
}

return parseTree;
};
})();

console.log(parseHTML(html));

关于c - 将简单的 HTML 解析成树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15647971/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com