
当http响应头设置为application/xml时,浏览器要求整个响应体必须是合法xml;若混入非xml文本(如提示字符串),将导致解析失败并报错“document is empty”。解决方法是根据实际输出内容类型正确设置content-type。
在PHP中使用DOMDocument::saveXML()生成并输出XML时,一个常见误区是:在已声明Content-Type: application/xml的前提下,向响应流中混入纯文本(如echo "Saving only the title part:\n";)。这会导致浏览器严格按XML解析整段响应——而开头的普通字符串显然不是合法XML声明或元素,因此解析器在第1行第1列即报错:“Document is empty”。
根本原因在于HTTP内容协商机制:header("Content-Type: application/xml; charset=ISO-8859-15") 明确告知浏览器“接下来的内容是XML文档”,浏览器便会启用XML解析器逐字节校验。一旦发现
✅ 正确做法是:根据实际输出内容选择匹配的Content-Type。
- 若仅输出纯XML(无额外说明文字),保持 application/xml 即可;
- 若需混合输出调试信息、描述文本与XML片段(如开发调试场景),则必须改用 text/plain 或 text/html:
// ✅ 开发调试推荐:使用 text/plain,避免XML解析约束
header("Content-Type: text/plain; charset=ISO-8859-15");
$doc = new DOMDocument('1.0', 'ISO-8859-15');
$doc->formatOutput = true;
$doc->preserveWhiteSpace = false;
$root = $doc->appendChild($doc->createElement('book'));
$title = $root->appendChild($doc->createElement('title'));
$title->appendChild($doc->createTextNode('This is the title'));
echo "Saving only the title part:\n";
echo $doc->saveXML($title); // 输出:This is the title ⚠️ 注意事项:
立即学习“PHP免费学习笔记(深入)”;
- saveXML($node) 仅序列化指定节点及其子树,不包含XML声明(),因此即使单独输出也非完整XML文档;
- 若需完整XML文档(含声明),应调用 $doc->saveXML()(无参数);
- 生产环境面向前端的XML接口,务必确保响应体100%符合XML规范,且Content-Type严格匹配;
- 字符编码需统一:DOMDocument构造时指定的编码、header()中的charset、以及XML声明中的encoding(如有)三者应一致,否则可能引发乱码或解析异常。
总结:XML输出不是简单的字符串拼接,而是受HTTP语义和浏览器解析规则双重约束的结构化响应。始终让Content-Type真实反映响应内容本质——这是避免此类“Document is empty”错误的关键原则。











