2013-07-17 38 views
0

method chaining with PHP is easy。但我需要这样的事情,如何用DOMDocument进行方法链接?

$xml = $dom->transformToThis('file1.xsl')->transformToThis('file2.xsl')->saveXML(); 

$books = $dom-> 
    transformToThis('file1.xsl')-> 
    transformToThis('file2.xsl')-> 
    getElementsByTagName('book'); 

很可能与PHP的DOMDocumentDOMNode


class DOMxx extends DOMDocument { 

    public function __construct() { 
      parent::__construct("1.0", "UTF-8"); 
    } 

    function trasformToThis($xslfile) { 
     $xsldom = new DOMDocument('1.0', 'UTF-8'); 
     $xsldom->load($xslfile); 

     $xproc = new XSLTProcessor(); 
     $xproc->importStylesheet($xsldom); 

     $this = $xproc->transformToDoc($this); // ERROR! 
     return $this; 
     } 
    } // class 

$this = X是在PHP中的无效的结构,我不明白workaround explained here。我可以使用诸如$this->loadXML($xproc->transformToDoc($this)->saveXML());之类的东西,但这是一个很大的过载,而问题是关于如何做正确的事情。

另一个(错误)的方式来尝试实现,

 function trasformToThis($xslfile) { 
     ... same ... 
     return $xproc->transformToDoc($this); // lost trasformToThis() method 
     } 

所以,在这种情况下,问题是“如何转换为DOMxx?”。

回答

2

怎么是这样的:

class DOMxx { 
    function __construct($version = '1.0', $encoding = 'UTF-8') { 
    $this->document = new DOMDocument($version, $encoding); 
    }             

    function __call($name, $args) { 
    $callback = array($this->document, $name); 
    return call_user_func_array($callback, $args); 
    } 

    function transformToThis($xslfile) { 
    $xsldom = new DOMDocument('1.0', 'UTF-8'); 
    $xsldom->load($xslfile); 

    $xproc = new XSLTProcessor(); 
    $xproc->importStylesheet($xsldom); 

    $this->document = $xproc->transformToDoc($this->document); 
    return $this; 
    } 
} 

而不是从DOMDocument延伸的,你把你里面的内部参考的DOMDocument对象类。大多数方法只是通过__call方法转发给这个内部对象。而transformToThis方法只是更新引用和transformToDoc调用返回的新文档。

+0

是的,它适用于方法链接,非常感谢!我会做更多的测试并等待其他答案,但我认为你是最好的答案。 –

0

你有transformToThis()有权修改原始对象明确的要求?我认为这将是清洁剂做这样的事情:

function trasform($xslfile) { 
    $xsldom = new DOMDocument('1.0', 'UTF-8'); 
    $xsldom->load($xslfile); 

    $xproc = new XSLTProcessor(); 
    $xproc->importStylesheet($xsldom); 

    $xml = $xproc->transformToXML($this); 
    $newDom = new DOMxx(); 
    $newDom.loadXML($xml); 
    return $newDom; 
    } 

如果你真的要修改原来的对象,我想这也将工作(该方法的这最后一部分):

$xml = $xproc->transformToXML($this); 
    $this.loadXML($xml); 
    return $this; 
+0

嗯...感谢线索,但没有人可以使用...关于你的问题,是的,原来的DOM被丢弃,我只需要转换。关于代码。第一个代码,我认为你可以用'return $ xproc-> transformToDoc($ this);'来简化,所有人都这么做。关于第二个问题,对不起,我编辑了我的问题,“我可以使用'$ this> loadXML($ xproc-> transformToDoc($ this) - > saveXML());'但是这是一个很大的过载。 –

+0

你能解释为什么“没有人可以使用”?你似乎没有给出理由。不,我的第一个例子不等于'return $ xproc-> transformToDoc($ this);',因为在我的例子中,返回的对象实际上有'transform()'方法,并且链接可以工作。至于第二个片段,创建DOM,获取其XML,然后将其加载到另一个DOM中没有意义。只需获取XML并将其加载到DOM中即可。 – JLRishe

+0

解释。我正在阅读本页面,并启用了“情境敏感”功能:** 1 **。 “没有人可以使用”=“没有任何线索可以用来解决我的问题,作为问题发布”。 ** 2 **。对不起,我尝试'返回$ xproc-> transformToDoc($ this);'它不起作用...它适合你?!后来我可以再试一次(!)。 ** 3 **。 “DOM = Load(SaveXML)”是开销,“DOM1 = DOM2”或“DOM1 =克隆DOM2”不是。 –