如何将HTML转换为有效的XHTML?

时间:2012-08-23 13:20:15

标签: javascript html xml parsing xhtml

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

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

我正在尝试使用与“img”节点匹配的正则表达式,并在节点的末尾应用斜杠,使其看起来像。

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

本质上,最终目标是确保节点关闭,开放节点在HTML中有效但显然不是XML。有没有正确的正则表达式buff能够提供帮助吗?

5 个答案:

答案 0 :(得分:14)

不要使用正则表达式,而是使用专用解析器。在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>

答案 1 :(得分:3)

您可以创建xhtml文档并导入/采用html元素。 Html字符串可以由HTMLElement.innerHTML属性解析。 关键点是使用Document.importNode()或Document.adoptNode()方法进行转换 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 a 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)。

答案 2 :(得分:2)

除了Rob W的answer之外,您还可以使用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中抛出错误,因为 text / html mimeType不是supported in IE9。适用于IE10和IE11。

答案 3 :(得分:1)

这将做得很好:

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

附录:在(不太可能的)事件中,您的代码包含包含尖括号的标记属性(不是vaild XML / XHTML BTW),那么这个会做得更好:

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

答案 4 :(得分:0)

为什么你想在浏览器DOM中修复一个XHTML无效的HTML文档?

它已经提供并已解析,您已经拥有了DOM。无效/错误形成的文档可能导致的任何解析错误已经发生,并且它不会是解决它的DOM上的正则表达式。

另外,请记住,几乎所有文档都被解析为HTML标记汤。如果您无法在服务器端修复文档,请忽略其在客户端的有效性/良好性。