【发布时间】:2010-09-08 10:07:16
【问题描述】:
在通过 PHP 通过 XSLT 转换 XML 时,我遇到了一个令人讨厌的编码问题。
问题可以总结/归纳如下:当我使用 XSLT 样式表复制(UTF-8 编码的)XHTML 文件时,某些字符显示错误。当我只显示同一个 XHTML 文件时,所有字符都正确显示。
以下文件说明了问题:
XHTML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>encoding test</title>
</head>
<body>
<p>This is how we dïßπλǽ ‘special characters’</p>
</body>
</html>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
PHP
<?php
$xml_file = 'encoding_test.xml';
$xsl_file = 'encoding_test.xsl';
$xml_doc = new DOMDocument('1.0', 'utf-8');
$xml_doc->load($xml_file);
$xsl_doc = new DOMDocument('1.0', 'utf-8');
$xsl_doc->load($xsl_file);
$xp = new XsltProcessor();
$xp->importStylesheet($xsl_doc);
// alllow to bypass XSLT transformation with bypass=true request parameter
if ($bypass = $_GET['bypass']) {
echo file_get_contents($xml_file);
}
else {
echo $xp->transformToXML($xml_doc);
}
?>
当这个脚本被这样调用时(通过例如http://localhost/encoding_test/encoding_test.php),转换后的 XHTML 文档中的所有字符都正常,除了 和 字符实体(它们是打开和关闭单引号)。我不是 Unicode 专家,但有两件事让我印象深刻:
- 所有其他字符实体都被正确解释(这可能暗示
&#145;和&#146;的 UTF-8 特性) - 然而,当 XHTML 文件直接显示时(例如通过http://localhost/encoding_test/encoding_test.php?bypass=true),所有个字符都会正确显示。
我想我已经在任何可能的地方为输出声明了 UTF-8 编码。其他人可能看到了什么是错误的并且可以纠正吗?
提前致谢!
罗恩·范登·布兰登
【问题讨论】: