【问题标题】:SimpleXML addChild issue when header sent发送标头时的 SimpleXML addChild 问题
【发布时间】:2014-01-27 11:32:02
【问题描述】:

我有这个代码:

$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 '&gt;' 从文档中它说 addChild 函数返回子的 SimpleXmlElement 。 通过取消注释注释行 $node-&gt;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

【问题讨论】:

  • 似乎正在处理sandbox.onlinephpfunctions.com,错误描述是什么?
  • 什么是错误。我测试的这段代码非常适合我
  • 可能你的错误在My Child node causes error -&gt; expect &gt;&gt;是XML中的保留字符,这可能会导致麻烦。立即测试...
  • 属性也要加上addAttribute()
  • @JTeisseire,$node 不存在是什么意思?它被声明为上面的行......他要求的是孩子的孩子,而不是孩子。

标签: php simplexml


【解决方案1】:

您看到的错误不是来自 SimpleXML,而是来自您的浏览器 - 这就是更改 HTTP 标头有效的原因。通过这一行,浏览器知道页面是 XML,并检查它是否有效;没有它,它假定它是 HTML,并且更宽松:

header('Content-type: text/xml');

如果您在浏览器中使用“查看源代码”,您会发现 PHP 的实际输出在两种情况下是相同的。另一个不错的测试是将 content-type 设置为 text/plain,这意味着浏览器根本不会解释输出,只是按原样显示。

因此,出于某种原因,SimpleXML 正在生成无效的 XML。这是因为 the -&gt;addChild() method 将要添加的元素的 name 作为其第一个参数,在您的情况下为 'erroNode';您传入的名称无效,其中还包含属性,稍后应使用-&gt;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',因为这是我们告诉它的。

结果是它尝试使用该“名称”放置一个结束标记,并以 &lt;/testNode attr="test Attribute"&gt; 结尾,这不是有效的 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    相关资源
    最近更新 更多