我正在使用cakephp的Xml或带有_serialize的XmlView将数组转换为xml,但是我无法添加样式表声明。
使用Array to XML时,是否可以在根标记之前添加:?
示例代码:
$value = array(
'tags' => array(
'tag' => array(
array(
'id' => '1',
'name' => 'defect'
),
array(
'id' => '2',
'name' => 'enhancement'
)
)
)
);
$xml = Xml::build($value);
echo $xml->asXML();
答案 0 :(得分:2)
Xml::build()
会返回SimpleXMLElement
(默认)或DOMDocument
的实例。后者有一个内置的方法来创建处理指令节点DOMDocument::createProcessingInstruction()
。
$xml = Xml::build($value, array('return' => 'domdocument'));
$style = $xml->createProcessingInstruction(
'xml-stylesheet',
'type="text/xsl" href="/path/to/style.xsl"'
);
$xml->insertBefore($style, $xml->firstChild);
echo $xml->saveXML();
这会输出类似:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/path/to/style.xsl"?>
<tags>
...
</tags>
另见
当使用XmlView
时,无法进入XML生成过程,因为它最终使用简单的单行生成:
return Xml::fromArray($data, $options)->asXML();
所以这里唯一的选择是获取生成的输出并再次处理它。例如,扩展XmlView
,覆盖_serialize()
方法,然后获取生成的输出,从中创建新的DOMDocument
实例,并在必要时添加PI节点。
这是一个(未经测试的)这种扩展视图的例子:
App::uses('XmlView', 'View');
class MyXmlView extends XmlView {
protected function _serialize($serialize) {
$xml = parent::_serialize($serialize);
if(isset($this->viewVars['_processingInstructions'])) {
$pi = array_reverse($this->viewVars['_processingInstructions']);
$doc = new DOMDocument();
$doc->loadXML($xml);
foreach($pi as $instruction) {
$node = $doc->createProcessingInstruction(
current(array_keys($instruction)),
current($instruction)
);
$doc->insertBefore($node, $doc->firstChild);
}
$xml = $doc->saveXML();
}
return $xml;
}
}
然后,在控制器中,可以设置_processingInstructions
视图变量来定义PI节点:
$_processingInstructions = array(
array('xml-stylesheet' => 'type="text/xsl" href="/path/to/style.xsl"')
);
$this->set(compact('tags', '_processingInstructions'));
$this->set('_serialize', 'tags');