DOMDocument groupping nodes, with clone, nodeClone, importNode, fragment... What the better way?

Posted by Peter Krauss on Programmers See other posts from Programmers or by Peter Krauss
Published on 2013-11-02T22:53:03Z Indexed on 2013/11/03 4:11 UTC
Read the original article Hit count: 354

Filed under:
|

A "DOMNodeList grouper" (groupList() function below) is a function that envelopes a set of nodes into a tag. Example:

INPUT

  <root><b>10</b><a/><a>1</a><b>20</b><a>2</a></root>

OUTPUT of groupList($dom->getElementsByTagName('a'),'G')

  <root><b>10</b>
     <G><a/><a>1</a><a>2</a></G>
  <b>20</b></root>

There are many ways to implement it, what is the better?

 function groupList_v1(DOMNodeList &$list,$tag,&$dom) {
      $list = iterator_to_array($list); // to save itens
      $n = count($list);
      if ($n && $list[0]->nodeType==1) {
             $T = $dom->createDocumentFragment();
             $T->appendChild($dom->createElement($tag));
             for($i=0; $i<$n; $i++) {
                  $T->firstChild->appendChild( clone $list[$i] );
       if ($i) $list[$i]->parentNode->removeChild($list[$i]);
             }
             $dom->documentElement->replaceChild($T,$list[0]);
       }//if
       return $n;
 }//func

 function groupList_v2(DOMNodeList &$list,$tag,&$dom) {
      $list = iterator_to_array($list); // to save itens
      $n = count($list);
      if ($n && $list[0]->nodeType==1) {
             $T = $dom->createDocumentFragment();
             $T->appendChild($dom->createElement($tag));
             for($i=0; $i<$n; $i++) 
                  $T->firstChild->appendChild( clone $list[$i] );
             $dom->documentElement->replaceChild($T,$list[0]);
             for($i=1; $i<$n; $i++)
                  $list[$i]->parentNode->removeChild($list[$i]);
       }//if
       return $n;
 }//func

 // ... YOUR SUGGESTION  ...

 // My ugliest
 function groupList_vN(DOMNodeList &$list,$tag,&$dom) {
       $list = iterator_to_array($list); // to save itens
       $n = count($list);
       if ($n && $list[0]->nodeType==1) {
      $d2 = new DOMDocument;
             $T = $d2->createElement($tag);
             for($i=0; $i<$n; $i++) 
                   $T->appendChild( $d2->importNode($list[$i], true) );
      $dom->documentElement->replaceChild( $dom->importNode($T, true), $list[0] );
             for($i=1; $i<$n; $i++)
                   $list[$i]->parentNode->removeChild($list[$i]);
       }//if
       return $n;
 }//func

Related questions: at stackoverflow, at codereview.

© Programmers or respective owner

Related posts about php

Related posts about dom