【问题标题】:php-script outputs xml file but breaks on special charactersphp-script 输出 xml 文件但在特殊字符上中断
【发布时间】:2011-12-09 15:39:51
【问题描述】:

我创建了这个 php 脚本,从我的数据库中创建一个 xml 文件:

<?php
header("Content-type: text/xml");
header("Expires: Mon, 26 Jul 1990 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");

$host = "localhost";
$user = "root";
$pass = "root";
$database = "flexapp";

$charToReplace = array("é", "è", "ê");
$charReplacements = array("e", "e", "e");

$linkID = mysql_connect($host, $user, $pass) or die("Could not connect to host.");
mysql_select_db($database, $linkID) or die("Could not find database.");

$query = "SELECT * FROM artists";
$artist_result = mysql_query($query, $linkID) or die("Data not found.");

$xml_output = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
$xml_output .= "<artists>\n";

for($x = 0 ; $x < mysql_num_rows($artist_result) ; $x++){
    $itemrow = mysql_fetch_assoc($artist_result);
    $xml_output .= "\t<artist>\n";
    $xml_output .= "\t\t<id>" . $itemrow['pk_artist_id'] . "</id>\n";
    $itemrow['artist_name'] = str_replace($charToReplace, $charReplacements,         $itemrow['artist_name']);
    $xml_output .= "\t\t<name>" . $itemrow['artist_name'] . "</name>\n";
    $xml_output .= "\t\t<picture>" . $itemrow['artist_pic'] . "</picture>\n";
    $xml_output .= "\t\t<twitter>" . $itemrow['artist_twitter'] . "</twitter>\n";
    $xml_output .= "\t</artist>\n";
}
$xml_output .= "</artists>\n";
echo $xml_output;
?>

我尝试将 é en ê 之类的字符替换为 e。

但它在浏览器中给出了这个错误:

This page contains the following errors:

error on line 23 at column 9: Encoding error

这是输出的xml:

<?xml version="1.0" encoding="UTF-8"?>
<artists>
<artist>
    <id>1155</id>
    <name>Have Heart</name>
    <picture>http://userserve-ak.last.fm/serve/126/29086375.jpg</picture>
    <twitter></twitter>
</artist>
<artist>
    <id>1156</id>
    <name>Dead Swans</name>
    <picture>http://userserve-ak.last.fm/serve/126/4781939.jpg</picture>
    <twitter></twitter>
</artist>
<artist>
    <id>1157</id>
    <name>Nirvana</name>
    <picture>http://userserve-ak.last.fm/serve/126/3991355.jpg</picture>
    <twitter></twitter>
</artist>
<artist>
    <id>1158</id>
    <name>Touchter>
</artist>

但最后一个(数据库中的名称是 Touché Amoré)应该和其他所有的一样,但不知何故,字符串没有被替换。

【问题讨论】:

  • 不确定它是否正是您想要的,但试试this也许会有所帮助
  • 我在做类似的事情时遇到的一件事是 MySQL 连接器 - 默认情况下,即使引擎将字符串存储在 utf-8 中,连接器也会以 iso-8859 将其拉出 - 1 除非您将字符集设置为连接器。见 mysql_set_charset() @php.net/manual/en/function.mysql-set-charset.php 如果你有 utf-8 格式的 XML 文件并且数据库是 utf-8 格式,你不应该需要将 'é' 类型的字符转换为 ' e'
  • 试过这个,但没有帮助。
  • 已将其扩展为完整答案 - 如果您已对其进行排序,请随意忽略;)

标签: php xml


【解决方案1】:

这可能是在打印之前对数据进行编码的问题。尝试使用utf8_encode()htmlentities()

function xmlencode($data) {
    $data = utf8_encode($data);
    $data = htmlentities($data);
    return $data;
}

然后

...
$xml_output .= "\t\t<picture>" . xmlencode($itemrow['artist_pic']) . "</picture>\n";
...

【讨论】:

  • &lt;name&gt; &lt;![CDATA[ Touch&amp;Atilde;&amp;copy; Amor&amp;Atilde;&amp;copy; ]]&gt; &lt;/name&gt; 关闭,这次它创建了完整的 xml 文件,但是正如你所看到的,仍然没有完成。
  • 删除$data = htmlentities($data);这行就可以了,谢谢!
  • 太棒了,很高兴有帮助:) 所以你将它与来自 rifat 的 CDATA[] 结合使用?应该这样做
  • 是的,不要使用 htmlentities(); HTML 实体 !== XML 实体;从技术上讲,标准 XML 只有 5 个实体。方便的是,它们与 htmlspecialchars() 使用的相同,因此这是一个更好的函数。 utf8_encode() 也有一个轻微的附带条件 - 它从 iso-8859-1 转换为 utf-8(我之前使用 € 符号和 Windows-1252 对此有所了解)。
  • 我遇到了类似的问题,我通过在输出 xml 数据之前运行以下查询解决了这个问题:mysql_query("SET NAMES 'utf8'");
【解决方案2】:

我猜这些字符被保存为实体,这就是为什么它不会替换并且会“破坏”你的 XML 输出。

您的脚本在这里就像一个魅力,并按预期输出。如果保存的值包含 é 而不是 é,您会通过 phpmyadmin 检查您的数据库吗?在这种情况下,您应该首先将实体解码为它们所代表的字符:http://php.net/manual/en/function.html-entity-decode.php

【讨论】:

【解决方案3】:

为什么不直接用 CDATA 包装名称变量

header('Content-Type: text/xml, charset=utf-8');

<name><![CDATA[Some very wired name]]></name>

而且,如果我是你,那么我将使用SimpleXML 来生成 XML。

【讨论】:

  • 我应该这样写: "\t\t\n" 或像这样的 "\t\t" 。 。 "\n"
  • 和第一个一样,但你在最后加上了]
  • "\t\t&lt;name&gt;&lt;![CDATA[" . $itemrow['artist_name'] . "]]&gt;&lt;/name&gt;\n"
  • &lt;name&gt;&lt;![CDATA[Touchue Colors]]&gt;&lt;/name&gt; 这是我现在的输出,仍然无法正常工作。
  • 我得到的和第一篇文章一样。
【解决方案4】:

如果您的数据库是 utf-8 格式,而您的 XML 文件是 utf-8 格式;您不需要对像 é 这样的“外来”字符进行任何转换。

首先,确保您的数据库表存储在 utf-8 中,然后将您的 XML 文件修复为 utf-8...

header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Content-type:text/xml;charset=utf-8"); //  <- add this line

下一步 - 确保您的 MySQL 连接器正在以 utf-8 格式从数据库中检索 utf-8 数据(默认情况下不会)。

$linkID = mysql_connect($host, $user, $pass) or die("Could not connect to host.");
mysql_select_db($database, $linkID) or die("Could not find database.");
mysql_set_charset("UTF8"); //  <-- add this line; NOTE MySQL doesn't use the hyphen in the utf-8 string

现在理论上,您所有的 é、ê 和 ñ(等等)字符应该正确地出现在 XML 文档中,而不需要任何转换或 CDATA 解析。

您需要转换的唯一字符是 IIRC,与 htmlspecialchars 转换的字符相同,即 &lt;&gt;&amp; 和(可选)引号和撇号。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多