如何将HTML转换为有效的XHTML

How to convert HTML to valid XHTML?

本文关键字:有效 XHTML 转换 HTML      更新时间:2023-09-26

我有一个HTML字符串,在这个例子中它看起来像

<img src="somepic.jpg" someAtrib="1" >

我正在尝试训练一个正则表达式,它将匹配"img"节点,并在节点的末尾应用斜线,使其看起来像。

<img src="somepic.jpg" someAtrib="1" />

本质上,这里的最终目标是确保节点是关闭的,打开的节点在HTML中是有效的,但显然不是XML。有什么regex buff可以帮助吗?

不要使用正则表达式,而是使用专用的解析器。在JavaScript中,使用DOMParser创建一个文档,然后使用XMLSerializer:对其进行序列化

var doc = new DOMParser().parseFromString('<img src="foo">', 'text/html');
var result = new XMLSerializer().serializeToString(doc);
// result:
// <html xmlns="http://www.w3.org/1999/xhtml"><head></head><body> (no line break)
// <img src="foo" /></body></html>

如果需要在nodejs后端使用xmldom,则必须使用xmldom。npm i xmldom

您可以创建一个xhtml文档并导入/采用html元素。当然,Html字符串可以通过HTMLElement.innerHTML属性进行解析。关键是使用Document.importNode()或Document.approveNode()方法进行转换html节点到xhtml节点:

var di = document.implementation;
var hd = di.createHTMLDocument();
var xd = di.createDocument('http://www.w3.org/1999/xhtml', 'html', null);
hd.body.innerHTML = '<img>';
var img = hd.body.firstElementChild;
var xb = xd.createElement('body');
xd.documentElement.appendChild(xb);
console.log('html doc:'n' + hd.documentElement.outerHTML + ''n');
console.log('xhtml doc:'n' + xd.documentElement.outerHTML + ''n');
img = xd.importNode(img); //or xd.adoptNode(img). Now img is an xhtml element
xb.appendChild(img);
console.log('xhtml doc after import/adopt img from html:'n' + xd.documentElement.outerHTML + ''n');

输出应为:

html doc:
<html><head></head><body><img></body></html>
xhtml doc:
<html xmlns="http://www.w3.org/1999/xhtml"><body></body></html>
xhtml doc after import/adopt img from html:
<html xmlns="http://www.w3.org/1999/xhtml"><body><img /></body></html>

Rob W的答案在chrome中不起作用(至少29及以下),因为DOMParser不支持"text/html"类型,XMLSerializer为chrome中的html文档生成html语法(not xhtml)。

除了Rob W的答案外,您还可以使用RegEx:提取正文内容

var doc = new DOMParser().parseFromString('<img src="foo">', 'text/html');
var result = new XMLSerializer().serializeToString(doc);
/<body>(.*)<'/body>/im.exec(result);
result = RegExp.$1;
// result:
// <img src="foo" />

注意:parseFromString(htmlString, 'text/html');会在IE9中引发错误,因为IE9中不支持text/html/b>mimeType。适用于IE10和IE11

这将做得很好:

result = text.replace(/(<img'b[^<>]*[^<>'/])>/ig, "$1 />");

附录:如果(不太可能)您的代码包含包含尖括号的标记属性(这不是有效的XML/XTML BTW),那么这一个会做得更好:

result = text.replace(/(<img'b(?:[^<>"''/]+|'[^']*'|"[^"]*")*)>/ig, "$1 />");