如何从不同的HTML生成器解析和规范化HTML?

时间:2009-06-11 16:36:57

标签: html perl parsing

这是此question的扩展。我正在尝试解析嵌入在Blogger博客的XML备份中的HTML片段,并使用InDesign标记将其重新标记。

Blogger没有为其任何帖子标准化HTML,帖子可以用Word,Windows Live Writer,原生Blogger界面或文本编辑器编写,从而产生大量不同形式的HTML。有些帖子不标记段落,只在段落之间使用双<br>个 - 其他帖子使用实际的<p>标记。

解析这种不标准的标签集合的最佳方法是什么?

此外,每篇文章都不是一个完整的HTML文件 - 只是一个插入模板的片段 - 这意味着没有要解析的整体HTML结构(<html><body></body></html>等)是否有任何对XML / HTML解析的影响?

以下是一些可能的示例,主要是标准HTML,缺少段落:

This is a section of a blog post. It has <a href="#">links</a> and lists and stuff. Weee....
<br>
<br>
Here's a list
<br/>
<br />
<ul><li>Item 1</li><li>Item 2</li><ul>
And another paragraph here...
<br>
<br/>
Etc.

Word HTML看起来像这样 - http://www.timeatlas.com/mos/images/stories/word_html_tags.png

4 个答案:

答案 0 :(得分:3)

答案 1 :(得分:2)

Word生成的HTML相对容易处理。我会摆脱所有的标签属性(除非你关心样式)。那将为您提供相当简单的HTML,然后您可以设置样式。

HTML::TokeParser::Simple可以帮助减轻这种压力。

至于其他东西,那将需要一些试验和错误。如果我能想到一些聪明的东西,我会更多地考虑这个问题并稍后发布。

稍后更新:

嗯,这件事让我有点畏缩,但似乎有效:

#!/usr/bin/perl

use strict;
use warnings;

use File::Slurp;
use Text::Markdown qw( markdown );

my $html = read_file \*DATA;

$html =~ s{(?:<br(:? ?/)*>)}{\n\n}g;

print markdown( $html );

__DATA__
This is a section of a blog post. It has <a href="#">links</a> and lists and stuff. Weee....
<br>
<br>
Here's a list
<br/>
<br />
<ul><li>Item 1</li><li>Item 2</li></ul>
And another paragraph here...
<br>
<br/>

输出:

<p>This is a section of a blog post. It has <a href="#">links</a> and lists and
stuff. Weee....</p>

<p>Here's a list</p>

<ul><li>Item 1</li><li>Item 2</li></ul>

<p>And another paragraph here...</p>

答案 2 :(得分:2)

正如我在另一个问题中所说,我喜欢XML::Twig。它可以处理XML和HTML。

答案 3 :(得分:0)

FWIW,我倾向于使用XML :: LibXML来满足我的所有XML和HTML需求。这是一个单线程,将一行“坏”HTML转换为格式良好的XHTML文档:

perl -MXML::LibXML -ne 'my $p = XML::LibXML->new->parse_html_string($_); print $p->toString'

在您的情况下,您可能希望使用DOM发出具有正确标记的新文档。这很简单; XML :: LibXML使用与JavaScript相同的W3C DOM。

举个例子,这个输入:

<p>Foo<p>Bar<br>Baz!

获取翻译成:

<?xml version="1.0" standalone="yes"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>Foo</p><p>Bar<br/>Baz!
</p></body></html>

这可能是您想要的,请记住,使用DOM进行翻译...不要担心这种打印的表示。