发送报头时SimpleXML addChild问题
我有以下代码:
$xml = new SimpleXMLElement('<myxml></myxml>');
$xml->addChild('testNode attr="test Attribute"');
$node = $xml->addChild('erroNode attr="My Child node causes error -> expect >"');
//$node->addChild('nodeChild attr="node Child"');
header('Content-type: text/xml');
echo $xml->asXML();
exit();
我可以通过$xml
创建带有属性的子节点,但不能通过$node
(子节点的子节点)创建,为什么?我收到错误error on line 2 at column 66: expected '>'
从文档中可以看出,addChild函数返回子对象的SimpleXmlElement。
通过取消注释行$node->addChild('nodeChild attr="node Child"');
进行检查
此外,只有在发送Header时才会发生这种情况,如果我评论Header并执行以下操作,我可以在页面源代码中看到正确的XML:
$xml = new SimpleXMLElement('<myxml></myxml>');
$xml->addChild('testNode attr="test Attribute"');
$node = $xml->addChild('erroNode attr="My Child node causes error -> expect >"');
$node->addChild('nodeChild attr="node Child"');
//header('Content-type: text/xml');
echo $xml->asXML();
exit();
我的PHP版本是5.4.9
解决方案
您看到的错误不是来自SimpleXML,而是来自您的浏览器--这就是更改HTTP头有效的原因。有了这一行,浏览器知道页面是XML,并检查它是否有效;如果没有它,它就假设它是HTML,并且更宽松:
header('Content-type: text/xml');
如果您在浏览器中使用"查看源代码",您会发现在这两种情况下来自PHP的实际输出是相同的。另一个不错的测试是将内容类型设置为text/plain
,这意味着浏览器根本不会解释输出,只按原样显示它。
->addChild()
method仅将要添加的元素的名称作为其第一个参数,在您的情况下'erroNode'
;您传入的无效名称也包含属性,应在以后使用->addAttribute()
添加。
如果我们进一步简化该示例,并查看生成的XML,我们可以看到发生了什么(这里是an online demo):
// Make browser show plain output
header('Content-type: text/plain');
// Working example
$xml = new SimpleXMLElement('<myxml></myxml>');
$xml->addChild('testNode attr="test Attribute"');
echo $xml->asXML();
echo "
";
// Broken example
$xml = new SimpleXMLElement('<myxml></myxml>');
$node = $xml->addChild('testNode attr="test Attribute"');
$node->addChild('test');
echo $xml->asXML();Child('testNode attr="test Attribute"');
$node->addChild('test');
echo $xml->asXML();
这将输出以下内容:
<?xml version="1.0"?>
<myxml><testNode attr="test Attribute"/></myxml>
<?xml version="1.0"?>
<myxml><testNode attr="test Attribute"><test/></testNode attr="test Attribute"></myxml>
第一个版本的XML似乎正在做正确的事情,因为它创建了一个"自结束标记"。但是,在第二个示例中,您可以看到SimpleXML认为标记名是'testNode attr="test Attribute"'
,而不仅仅是'testNode'
,因为我们就是这么告诉它的。
结果是它尝试使用该"name"放置一个结束标记,并以</testNode attr="test Attribute">
结束,而</testNode attr="test Attribute">
不是有效的XML。
可以说,SimpleXML应该可以保护您免受这种情况的影响,但现在您知道了,您可以轻松地修复代码(demo):
// Make browser show plain output
header('Content-type: text/plain');
// Fixed example
$xml = new SimpleXMLElement('<myxml></myxml>');
$node = $xml->addChild('testNode');
$node->addAttribute('attr', 'test Attribute');
$node->addChild('test');
echo $xml->asXML();
现在,SimpleXML知道标记仅称为'testNode'
,因此可以在需要时创建正确的结束标记:
<?xml version="1.0"?>
<myxml><testNode attr="test Attribute"><test/></testNode></myxml>
相关文章