2010-05-19

PHP解析HTML和loadHTML乱码

Views: 34335 | 1 Comment

为了对 RSS 输出的博客文章进行重新格式化, 比如去掉过于花哨的样式, 去除 JavaScript 脚本代码, 去除 onclick 等, 所以写了相关的 PHP 代码, 使用 DOM 模块.

1. 乱码解决

毫无疑问, 一上来就遇到了乱码问题, 虽然我已经按文档所述, 所有的字符使用 UTF-8 编码:

$html = '<p>你好</p>';
$dom = new DOMDocument();
@$dom->loadHTML($html);
echo $dom->documentElement->nodeValue;

但是, 如果改成:

$html = '<p>你好</p>';
$dom = new DOMDocument();
@$dom->loadXML($html);
echo $dom->documentElement->nodeValue;

就没有问题. 后来才发现, 原来 loadHTML 会依赖 HTML 中的声明 meta 标签. 如果没有这样的标签, 就当作 iso-8859-1 字符集, 所以乱码. 要解决, 就给字符串加上这样的一个标签在头部:

$meta = '<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>';
@$dom->loadHTML($meta . $html);

2. 递归

HTML/XML 是递归结构, 所以一定会递归遍历:

function _pretty_html_node($node){
	// 递归终止条件
	// 1. XML_TEXT_NODE
	// 2. XML_ELEMENT_NODE
	// 3. 没有子节点

	foreach($node->childNodes as $n){
		$child_text .= _pretty_html_node($n);
	}

	// 然后对不同的标签做不同的处理
	switch($tag){
		case 'a':
			$href = $node->getAttribute('href');
			$text .= "<a href=\"$href\">$child_text</a>";
		...
	}

	return $text;
}

3. 转义字符处理

对于文本节点, 其 nodeValue 要经过 htmlspeciachars() 转义. 因为读取 HTML/XML 时, 会对文本进行反转义, 比如 &gt; 在内存中已经是 >了.

下载源码: pretty_html.php

Related posts:

  1. C# 版的 SimpleXML
  2. 自架设Apache服务器过程中的网页乱码问题
  3. 如何让 PHP json_encode 函数不转义中文?
  4. C++ STL 迭代器的失效原则
  5. 强大的纯JS数据图工具-flot
Posted by ideawu at 2010-05-19 13:44:57 Tags: ,

One Response to "PHP解析HTML和loadHTML乱码"

Leave a Comment