带样式表的CakePHP XmlView(XSL)

时间:2014-06-05 22:20:52

标签: php xml cakephp

我正在使用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();

1 个答案:

答案 0 :(得分:2)

使用内置DOMDocument方法

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输出

当使用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');