【问题标题】:How to do method chaining with DOMDocument?如何使用 DOMDocument 进行方法链接?
【发布时间】:2013-07-17 21:49:40
【问题描述】:

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?”。

【问题讨论】:

    标签: php xslt chaining


    【解决方案1】:

    这样的事情怎么样:

    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 扩展,而是在DOMxx 类中保留对DOMDocument 对象的内部引用。大多数方法只是通过__call 方法转发到这个内部对象。而transformToThis 方法只是用transformToDoc 调用返回的新文档更新引用。

    【讨论】:

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

    您有明确的要求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; 
    

    【讨论】:

    • 嗯...感谢线索,但没有人可以使用...关于你的问题,是的,原来的DOM被丢弃了,我只需要转换的。关于代码。第一个代码,我想你可以用return $xproc->transformToDoc($this); 来简化,所以,这是所有人都会做的。关于第二个,对不起,我用“我可以使用$this>loadXML( $xproc->transformToDoc($this)->saveXML() );,但它是一个很大的超载”编辑了我的问题。
    • 能否请您解释一下为什么“没有人可以使用”?你好像没有给出理由。不,我的第一个示例不等同于return $xproc->transformToDoc($this);,因为在我的示例中,返回的对象实际上将具有transform() 方法并且链接将起作用。至于第二个 sn-p,创建一个 DOM,获取它的 XML,然后将其加载到另一个 DOM 中是没有意义的。只需获取 XML 并将其加载到 DOM 中即可。
    • 解释。我正在阅读此页面,并启用“上下文相关”:1。 "没有人可以使用" = "您的任何线索都不能用作我的问题的解决方案,作为问题发布"。 2。抱歉,我尝试return $xproc->transformToDoc($this); 但它不起作用......它对你有用吗?!稍后我可以再试一次(!)。 3。 “DOM = Load(SaveXML)”是开销,“DOM1 = DOM2”或“DOM1 = clone DOM2”不是。
    • 2.不,return $xproc->transformToDoc($this);不起作用,但这与我在第一个示例中所做的不同。 3. 可能会有少量开销,但可能太小而无所谓,这比制作一些过度包装类要好,这将是另一种选择。顺便说一句,DOM1 = clone DOM2 肯定会有开销。
    猜你喜欢
    • 2022-01-22
    • 2018-03-21
    • 2018-05-10
    • 1970-01-01
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多