数据库转XML时特殊字符ü无法输出及'uuml实体未定义'错误的修复咨询
解决DOMDocument创建XML时特殊字符'ü'的实体错误问题
这个问题我之前也碰到过,核心原因是XML和HTML对实体的支持范围不一样:XML默认只认5个预定义实体(<、>、&、"、'),而ü是HTML专属的实体,XML解析器根本不认识它。你用saveHTML()输出XML内容时,DOMDocument会自动把'ü'转成ü,自然就触发了实体未定义的错误。
具体修复步骤:
用
saveXML()替代saveHTML()输出XML
你的代码最后用了echo $xml->saveHTML();,这是专门输出HTML格式的方法,会把特殊字符转成HTML实体。换成saveXML()就能直接输出UTF-8编码的XML内容,保留'ü'原字符而不做不必要的实体转换。明确DOMDocument的UTF-8编码配置
虽然你初始化时已经指定了UTF-8,但额外加一行$xml->encoding = 'UTF-8';可以彻底避免隐式编码转换的坑。确保数据库连接是UTF-8编码
从数据库读数据时如果编码不对,后续处理也会出问题。可以在连接数据库后执行一句编码设置,保证读取到的makine_cinsi是正确的UTF-8格式。
修正后的完整代码:
<?php session_start(); $yol = $_SESSION[ 'kok_dizin' ] . "DatabaseOperations/ConnectionOperations.php"; require_once( $yol ); $connect = new Connection(); $connect->BaglantiyiAc(); // 新增:设置数据库连接编码为UTF-8,避免读取数据时乱码 $connect->connectionKey->exec("SET NAMES 'utf8mb4'"); $arrayMakineler = array(); $getMakinelerSql = "select mac_id,makine_cinsi from envanter_listesi where makine_cinsi!='' and makine_cinsi!='(BOŞ)'"; $queryResultMakineler = $connect->connectionKey->query( $getMakinelerSql, PDO::FETCH_BOTH ); if ( $queryResultMakineler->rowCount() > 0 ) { foreach ( $queryResultMakineler as $row ) { array_push( $arrayMakineler, $row ); } $connect->BaglantiyiKapat(); } header( "Content-Type: application/xml; charset=UTF-8" ); $xml = new DOMDocument( '1.0', 'UTF-8' ); // 明确指定编码,强化UTF-8配置 $xml->encoding = 'UTF-8'; // 可选:开启格式化输出,让XML更易读 $xml->formatOutput = true; $makineler = $xml->createElement( 'makine_cinsleri' ); for ( $i = 0; $i < count( $arrayMakineler ); $i++ ) { $mac_id = $arrayMakineler[ $i ][ "mac_id" ]; $makine_cinsi = $arrayMakineler[ $i ][ "makine_cinsi" ]; $makine = $xml->createElement( 'makine' ); $id = $xml->createElement( 'id', $mac_id); // 直接使用数据库读取的原数据,不需要硬编码测试用的"ü" $cins = $xml->createElement( 'cins', $makine_cinsi ); $makine->appendChild( $id ); $makine->appendChild( $cins ); $makineler->appendChild( $makine ); } $xml->appendChild( $makineler ); // 替换saveHTML()为saveXML(),正确输出XML格式 echo $xml->saveXML(); ?>
额外说明:
如果硬要在XML里用HTML实体(非常不推荐),你需要手动在XML开头定义实体,比如添加<!DOCTYPE makine_cinsleri [<!ENTITY uuml "ü">]>,但这种方法会增加代码复杂度,远不如直接用UTF-8原生字符来得简单可靠。
内容的提问来源于stack exchange,提问作者Emrah Çalışkan
相关产品推荐
相关产品推荐

