How to do method chaining with DOMDocument?

核能气质少年 提交于 2019-12-08 11:21:23

问题


Do method chaining with PHP is easy. But I need something like this,

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

or

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

It is possible with PHP's DOMDocument or DOMNode?


  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

The $this = X is a invalid construct in PHP, and I not understand the workaround explained here. I can use something like $this->loadXML( $xproc->transformToDoc($this)->saveXML() ); but it is a big overload, and the question is about how to do the correct thing.

Another (wrong) way to try to implement,

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

so, in this case the question is "How to cast to DOMxx?".


回答1:


How about something like this:

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; 
  }
}

Instead of extending from DOMDocument, you keep an internal reference to a DOMDocument object inside your DOMxx class. The majority of methods are just forwarded to this internal object via the __call method. And the transformToThis method just updates the reference with the new document returned from the transformToDoc call.




回答2:


Do you have a definite requirement that transformToThis() has to modify the original object? I'd think it would be cleaner to do something like this:

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; 
  }

If you really want to modify the original object, I imagine this would work also (for that last part of the method):

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


来源:https://stackoverflow.com/questions/17710890/how-to-do-method-chaining-with-domdocument

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!