我有这段代码:
$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"');
进行检查
它也只发生在标题发送时,如果我评论标题并且如下所示我可以在页面源中看到正确的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
答案 0 :(得分:0)
您看到的错误不是来自SimpleXML,而是来自您的浏览器 - 这就是更改HTTP标头的原因。使用此行,浏览器知道页面是XML,并检查它是否有效;没有它,它假定它是HTML,并且更宽松:
header('Content-type: text/xml');
如果您在浏览器中使用“查看源代码”,您会发现PHP的实际输出在两种情况下都是相同的。另一个不错的测试是将内容类型设置为text/plain
,这意味着浏览器根本不会解释输出,只是按原样显示。
因此,由于某种原因,SimpleXML生成无效的XML。这是因为the ->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 "\n";
// 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">
,这是无效的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>