Javascript 将HTML字符串转换为有组织的对象
Lang:NodeJS 我使用的是文本编辑器,我得到的输出字符串如下Javascript 将HTML字符串转换为有组织的对象,javascript,node.js,Javascript,Node.js,Lang:NodeJS 我使用的是文本编辑器,我得到的输出字符串如下 <p>This is <strong>a <a href="#">test</a></strong></p> 等等 我尝试了正则表达式方法,并把它拆分成各种逻辑来构造成一个结构化对象,但这不是最好的方法,因为如果将来我在文本的中间写“代码>测试,它将失败。” 您将如何处理此问题?使用cheerio库(或您选择的任何其他html解析器库
<p>This is <strong>a <a href="#">test</a></strong></p>
等等
我尝试了正则表达式方法,并把它拆分成各种逻辑来构造成一个结构化对象,但这不是最好的方法,因为如果将来我在文本的中间写“代码>测试<代码>,它将失败。” 您将如何处理此问题?
使用cheerio库(或您选择的任何其他html解析器库)并按照您的意愿操作“DOM节点”对象。如果您希望操作简单,或者可以帮助完成此操作。例如,使用htmlparser2
和domhandler
(from):
//解析器帮助程序
从“htmlparser2”导入{Parser};
从“DomHandler”导入{DomHandler};
//递归地获取所有文本内容
常量getAllText=(节点)=>{
返回node.children.map(n=>{
如果(n.type=='text'){
返回n.data.trim(“\n\r”);
}
//丢弃“小”标签
如果(n.name=='small'){
返回“”
}
返回getAllText(n);
}).加入(“”)
}
//解析包含UL/LI/a树的HTML数据
const parseMenu=(数据)=>{
const parseLink=(link)=>{
const name=getAllText(链接);
常量代码=link.attribs['data-value']?.trim(“\n\r”);
返回{
名称
…(代码?{code}:{}),
}
}
const parseLi=(li)=>{
const ul=li.children.find(({type,name})=>type==='tag'&&name=='ul');
const link=li.children.find(({type,name})=>type==='tag'&&name=='a');
返回{
…(链接?解析链接(链接):{}),
…(ul{children:parseUl(ul)}:{}),
}
}
const parseUl=(ul)=>{
返回ul.children.filter(({type,name})=>type==='tag'&&name=='li').map(child=>{
返回parseLi(儿童);
});
}
让结果;
const handler=新的DomHandler((错误,dom)=>{
如果(错误){
//处理错误
}否则{
//解析完成,做点什么
结果=parseUl(dom[0]);
}
});
const parser=新的解析器(处理程序);
写入(数据);
parser.end();
返回结果;
}
要做到这一点,您需要定义预定义的规则,以及输入和预期输出之间的明确关系,如我所见,您忽略了第二个
,也忽略了
元素,因此,您的目标只是包含内容的段落元素?这实际上只是一个示例,我错过了第二个,因为我太懒了,没有写出整个对象:d像这样的HTML,您希望得到什么?这是
?我真的不知道如何循环使用HTML字符串。你能解释一下吗?问题是,我从一开始就不知道HTML是如何构造的,Cheerio希望我总是以$('p')开头,但问题是它可以以a或a等开头。在上面复制的示例中,解析器希望HTML是带有childs的
元素。如果您需要更通用的东西,可以获取dom[0]
(在本例中)并从开关(dom[0].tag)
开始,而不是直接使用parseUl(dom[0])
。如果所有内容都可以包含在所有内容中,那么这应该包含在一个递归函数中,可能名为parseDispatcher
(或类似的东西)。工具提供的是将HTML解析为一个可以遍历或查询的数据结构。如何将其转换为所需的数据形状取决于您自己。例如:您是否希望一个包含所有对象的唯一JSON对象按照原始DOM中的结构相互转换?或者,您可能想要一个对象数组,其中不包含或包含其原始DOM子结构的一部分?或者您希望分离的数组包含DOM中找到的每一种类型的对象?但例如,像这样的这就是a
。如何在每个步骤中跟踪DOM对象?当您从一开始就知道HTML对象时,当然很容易,因为您可以在下一步使用它,等等。但是当它每次都不同时,这似乎是不可能的。我可能会回到正则表达式拆分逻辑:P
[{type: "text", text: "This is ", bold: false}, {type: "text", text: "a ", bold: true}, {type: "link", text: "test", bold: true, href: "#}]