我正在使用CakePHP的Xml核心库在视图中生成XML :
$xml = Xml::build($data, array('return' => 'domdocument')); echo $xml->saveXML();
视图由控制器通过数组提供:
$this->set( array( 'data' => array( 'root' => array( array( '@id' => 'A & B: OK', 'name' => 'C & D: OK', 'sub1' => array( '@id' => 'E & F: OK', 'name' => 'G & H: OK', 'sub2' => array( array( '@id' => 'I & J: OK', 'name' => 'K & L: OK', 'sub3' => array( '@id' => 'M & N: OK', 'name' => 'O & P: OK', 'sub4' => array( '@id' => 'Q & R: OK', '@' => 'S & T: ERROR', ), ), ), ), ), ), ), ), ) );
无论出于何种原因,CakePHP都会发出这样的内部调用:
$dom = new DOMDocument; $key = 'sub4'; $childValue = 'S & T: ERROR'; $dom->createElement($key, $childValue);
…会触发PHP警告:
Warning (2): DOMDocument::createElement(): unterminated entity reference T [CORE\Cake\Utility\Xml.php, line 292
…因为(如记录所示)DOMDocument::createElement不会转义值。但是,如测试用例所示,它仅在某些节点中执行此操作。
DOMDocument::createElement
我是在做错什么,还是刚遇到CakePHP中的错误?
问题似乎出在具有属性和值的节点中,因此需要使用以下@语法:
@
'@id' => 'A & B: OK', // <-- Handled as plain text 'name' => 'C & D: OK', // <-- Handled as plain text '@' => 'S & T: ERROR', // <-- Handled as raw XML
我写了一些辅助函数:
protected function escapeXmlValue($value){ return is_null($value) ? null : htmlspecialchars($value, ENT_XML1, 'UTF-8'); }
…并在创建数组时注意手动调用它:
'@id' => 'A & B: OK', 'name' => 'C & D: OK', '@' => $this->escapeXmlValue('S & T: NOW WORKS FINE'),
由于文档中没有提及它,因此很难说它是错误还是功能。