我有一个 PHP 脚本可以导入和解析 XML 文件并将数据保存到数据库中:
- 数据库整理:
utf8_general_ci
,字符集:utf8
- 页面的字符集:
utf-8
- XML 文件:
ANSI
, 包含智能引号(来自 MS Word)
所以在导入过程中我做了一个 utf8_encode()
在保存到数据库并随后显示在页面上之前对 XML 文件中的文本进行处理。
但是当成功导入并保存到数据库中时,
- 数据库:智能引号保存为
?
字符(从CMD查看) - 页面:智能引号显示为方框
关于为什么智能引号没有被正确转换的任何想法,即使在使用 utf8_encode()
时也是如此?
编辑:
@Tomalak:XML 文件实际上是 .txt
,没有 XML 声明( <?xml ... ?>
),也没有根元素。我的脚本实际上添加了一个根元素,以便解析器工作:
utf8_encode('<article>' . file_get_contents($xmlfile) . '</article>');
似乎我需要添加一个 XML 声明..?如果是这样,它应该是什么样子?
最佳答案
如果您的 XML 字符串(即文件内容)未编码为 UTF-8,则您需要一个表示文件编码的 XML 声明。如果缺少 XML 声明,解析器将采用 UTF-8。
只要您不使用“特殊”字符(即 ASCII 范围之外的任何字符),即使您的文件不是 真正 UTF-8 编码,它也无需声明即可工作。这是因为 UTF-8 与 ASCII 字节兼容。但是,一旦使用了其中一个代码页上的字符(如“智能引号”),它就会中断,因为它们在 UTF-8 中由不同的字节表示。
在您的情况下,有一些传统编码的文本文件,您用根元素包装这些文件以将它们转换为格式正确的 XML。因此您需要自己添加 XML 声明:
'<?xml encoding="Windows-1252"?><article>'.file_get_contents($xmlfile).'</article>'
通过这种方式,您可以指示 DOMDocument
如何解释字符串中的字节。我为您假设了 Windows-1252
,因为您说的是 ANSI 并提到了弯引号。
事实上,95% 的时间这就是人们真正的意思,即使在 Linux 上,即使他们说 ISO-8859-1
(或 latin-1
),这几乎是,但完全是同一件事。
为了更加确保您可以在十六进制编辑器中打开您的文本文件,找出一些特殊字符并将它们的字节值与可疑编码进行比较。对于 Windows-1252
.对于大引号,预期的字节值为:
“
147 (0x93)”
148 (0x94)
一旦声明了字符串中各个字节的含义,DOMDocument
就可以理解它们并做正确的事情。
当涉及到数据库时,我强烈怀疑正在进行某种自动编码转换。我承认我对 PHP/mySQL/Unicode 集成的了解还不够肯定。
关于php - 智能引号无法正确转换为 UTF8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9394210/