Php-script输出XML文件,但在特殊字符上中断


php-script outputs xml file but breaks on special characters

我已经创建了这个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;
?>

我试着用e来替换像" en ê"这样的字符。

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

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)应该像所有其他的,但不知何故字符串没有被替换。

这可能是在打印前对数据进行编码的问题。尝试使用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";
...

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

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

为什么不像

那样用CDATA包装name变量呢?
header('Content-Type: text/xml, charset=utf-8');

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

如果我是你,我会使用SimpleXML来生成XML。

如果您的数据库是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转换的字符相同,即<, >, &和(可选)引号和撇号。