PHP调用simplexml_load_string读电商XML报nbsp实体未定义错误怎么解决
问题原因
XML标准仅预定义了<、>、&、"、'5种实体, 是HTML专属的实体符号,未在XML规范中默认声明,因此XML解析器识别时会抛出未定义报错,你遇到的报错就是<note>节点内的 导致的。
解决方案
根据你是否能修改源XML文件,可选择以下任意一种方案:
方案1:直接替换实体(最便捷,无需修改源文件)
在调用simplexml_load_string前,先将XML内容中的 替换为XML兼容的不间断空格实体 ,也可以根据业务需求替换为普通空格:
// 从第三方获取到的原始XML内容 $raw_xml = '你的XML内容字符串'; // 替换 为XML可识别的实体 $processed_xml = str_replace(' ', ' ', $raw_xml); // 加载处理后的XML $xml = simplexml_load_string($processed_xml);
方案2:为XML补充实体定义
如果不想替换内容,可以给XML添加 的实体声明:
- 如果你可以修改源XML:在XML开头的DOCTYPE部分添加实体定义即可:
<!DOCTYPE product [ <!ENTITY nbsp " "> ]> <product> <!-- 剩余XML内容 --> </product> - 如果你无法修改源XML:可以在PHP中加载前动态拼接声明:
$doctype = '<!DOCTYPE product [<!ENTITY nbsp " ">]>'; $processed_xml = $doctype . $raw_xml; $xml = simplexml_load_string($processed_xml);
方案3:用DOMDocument的HTML兼容模式解析
如果XML内混有大量HTML标签和实体,逐个替换成本太高,可以用DOMDocument的HTML加载模式直接兼容HTML特性,再转为SimpleXML对象使用:
$dom = new DOMDocument(); // 关闭非关键错误提示,避免HTML不规范导致的警告 libxml_use_internal_errors(true); // 按HTML格式加载XML内容,自动识别HTML实体 $dom->loadHTML($raw_xml); libxml_clear_errors(); // 转为SimpleXML对象 $xml = simplexml_import_dom($dom);
方案4:将富文本内容包裹进CDATA块(适合可修改源XML的场景)
XML解析器会直接忽略CDATA块内的所有标签、实体语法,如果你可以修改源XML,直接把<note>节点内的富文本内容用<![CDATA[ ]]>包裹即可:
<note><![CDATA[ <p style="margin: 0"><span style='font-family: "Open Sans",sans-serif; font-size: 19px; font-weight:600; color: #1e55fa'>Ürün İsmi:</span></p> <!-- 剩余富文本内容 --> ]]></note>
内容的提问来源于stack exchange,提问作者furkan bozkurt
相关产品推荐
相关产品推荐

