这是与HTML DOM answer 类似的解决方案。如果您的 HTML 有效,您可以尝试将其解析为 XML。这里的优点是,InternetExplorer.Application COM 对象为每个页面加载加载整个完全膨胀的 Internet Explorer 实例,而不是只加载一个 dll (msxml3.dll)。这应该有望更有效地处理多个文件。不利的一面是 XML 解析器对标签结构的有效性很挑剔。例如,如果您有一个未关闭列表项的无序列表:
<ul>
<li>Item 1
<li>Item 2
</ul>
... Web 浏览器可以理解这一点,但 XML 解析器可能会出错。无论如何,值得一试。我刚刚在一个包含 500 个相同 HTML 文件的目录上进行了测试,不到一分钟就完成了。
@if (@CodeSection == @Batch) @then
@echo off
setlocal
for %%I in ("*.htm") do (
cscript /nologo /e:JScript "%~f0" "%%~fI"
)
rem // end main runtime
goto :EOF
@end
// end batch / begin JScript chimera
WSH.StdOut.Write('Checking ' + WSH.Arguments(0) + '... ');
var fso = WSH.CreateObject('scripting.filesystemobject'),
DOM = WSH.CreateObject('Microsoft.XMLDOM'),
htmlfile = fso.OpenTextFile(WSH.Arguments(0), 1),
html = htmlfile.ReadAll().split(/<\/head\b.*?>/i),
head = html[0] + '</head>',
body = html[1].replace(/<\/html\b.*?>/i,''),
changed;
htmlfile.Close();
// attempt to massage body string into valid XHTML
var self_closing_tags = ['area','base','br','col',
'command','comment','embed','hr','img','input',
'keygen','link','meta','param','source','track','wbr'];
body = body.replace(/<\/?\w+/g, function(m) { return m.toLowerCase(); }).replace(
RegExp([ // should match <br>
'<(',
'(' + self_closing_tags.join('|') + ')',
'([^>]+[^\/])?', // for tags with properties, tag is unclosed
')>'
].join(''), 'ig'), "<$1 />"
);
DOM.loadXML(body);
DOM.async = false;
if (DOM.parseError.errorCode) {
WSH.Echo(DOM.parseError.reason);
WSH.Quit(0);
}
for (var d = DOM.documentElement.getElementsByTagName('div'), i = 0; i < d.length; i++) {
var p = d[i].getElementsByTagName('p');
if (p && p[0]) {
// move contents of p node up to parent
while (p[0].hasChildNodes()) p[0].parentNode.insertBefore(p[0].firstChild, p[0]);
// delete now empty p node
p[0].parentNode.removeChild(p[0]);
changed = true;
}
}
html = head + DOM.documentElement.xml + '</html>';
if (changed) {
htmlfile = fso.CreateTextFile(WSH.Arguments(0), 1);
htmlfile.Write(html);
htmlfile.Close();
WSH.Echo('Fixed!');
}
else WSH.Echo('Nothing to change.');