如何使用DOMDocument进行方法链接?

时间:2013-07-17 21:49:41

标签: php xslt chaining

method chaining with PHP is easy。但我需要这样的东西,

$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 个答案:

答案 0 :(得分: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类中保留对DOMxx对象的内部引用。大多数方法只是通过__call方法转发到此内部对象。 transformToThis方法只是使用transformToDoc调用返回的新文档更新引用。

答案 1 :(得分: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;