0

I have a $content with

<div class="slidesWrap">
   <div class="slidesСontainer">
      <div class="myclass"> 
        ...
      </div>
      <div class="myclass">
        ...
      </div>
      ...
      ...
      <div class="myclass">
        ...
      </div>
   </div>
   <div class="nav">
      ...
   </div>
</div>
some other text here, <p></p> bla-bla-bla

I would like to remove via PHP all the divs with class="myclass" except the first one, and add another div instead of others, so that the result is:

<div class="slidesWrap">
   <div class="slidesСontainer">
      <div class="myclass"> 
        ...
      </div>
      <div>Check all divs <a href="myurl">here</a></div>
   </div>
   <div class="nav">
      ...
   </div>
</div>
some other text here, <p></p> bla-bla-bla

Would be grateful if someone can point me a solution.

UDATE2:

some similar question here from that I came up with the following test code:

$content = '<div class="slidesWrap">
   <div class="slidesСontainer">
      <div class="myclass">
      </div>
      <div class="myclass">
      </div>
      <div class="myclass">
      </div>
   </div>
   <div class="nav">
  </div>
  </div>
 some other text here, <p></p> bla-bla-bla';

$dom = new DOMDocument();
$dom->loadHtml($content);

$xpath = new DOMXPath($dom);
foreach ($xpath->query('//*[@class="myClass" and position()>1]') as $liNode) {
    $liNode->parentNode->removeChild($liNode); 
}

echo $dom->saveXml($dom->documentElement);

Any ideas where I can test it?

Community
  • 1
  • 1
Denis
  • 1,526
  • 6
  • 24
  • 40

3 Answers3

1

Here is what you are looking for (similar to your edit, but it removes the added html tags):

$doc = new DOMDocument();
$doc->loadHTML($content);

$xp = new DOMXpath($doc);
$elements = $xp->query("//div[@class='myclass']");

if($elements->length > 1)
{
    $newElem = $doc->createElement("div");
    $newElem->appendChild($doc->createTextNode("Check all divs "));
    $newElemLink = $newElem->appendChild($doc->createElement("a"));
    $newElemLink->setAttribute("href", "myurl");
    $newElemLink->appendChild($doc->createTextNode("here"));

    $elements->item(1)->parentNode->replaceChild($newElem, $elements->item(1));     

    for($i = $elements->length - 1; $i > 1 ; $i--)
    {
        $elements->item($i)->parentNode->removeChild($elements->item($i));
    }
}

echo $doc->saveXML($doc->getElementsByTagName('div')->item(0));
Aaron J Spetner
  • 2,117
  • 1
  • 18
  • 30
  • Thank you for your reply. Do you know here I can check the code on-line? I try http://ideone.com but it seems not to process it? – Denis Jan 05 '12 at 14:53
  • You needed to add php tags (see http://ideone.com/QFrYb), but it doesn't look like ideaone supports DOMDocument. Where is this code to be run? Don't you have a development server or something? – Aaron J Spetner Jan 05 '12 at 16:34
  • thank you, it does work. p/s/ I have a server, but wanted to try it before applying it to my site. – Denis Jan 05 '12 at 18:05
  • funny enough, it does not 'like' some text after div's, like "some other text here,

    bla-bla-bla"
    – Denis Jan 05 '12 at 18:38
  • that seems to do the trick 'echo $doc->saveXML($doc->documentElement);' – Denis Jan 05 '12 at 18:44
-1
$var = ':not(.myClass:eq(1))';   
$var.removeClass("myClass");
$var.addClass("some_other_Class");
Prashant Singh
  • 3,725
  • 12
  • 62
  • 106
  • wouldn't this only remove the class, and not the div itself – Ayush Jan 05 '12 at 13:47
  • Yup, but he said, he need to remove a div and then add another. I think its equivalent to removing one and adding another to the same div in one selection – Prashant Singh Jan 05 '12 at 13:49
  • thank you for your suggestion, do you mean it like this $content(':not(.myClass:eq(1))).removeClass("myClass") ? – Denis Jan 05 '12 at 13:50
  • no, he said he needs to replace multiple divs with one div. So, if he initially had n divs, his final product needs to have 2 divs. One for the first div, and 1 for the remaining (n-1) divs – Ayush Jan 05 '12 at 13:52
  • Whats $content, I think my code will work fine without any modification for the given snippet of code – Prashant Singh Jan 05 '12 at 13:52
  • @Denis: this is jquery. It won't serve your purpose – Ayush Jan 05 '12 at 13:53
  • @PrashantSingh: Your new code is also adding/removing classes (CSS classes). He needs to add/remove the entire div itself (HTML element) – Ayush Jan 05 '12 at 13:55
  • What language/library/what is this? It's certainly neither PHP nor jQuery. – deceze Jan 05 '12 at 14:22
-2

If I got you right, you've got a string called $content with all that content in it It's not the best solution I guess but here is my attempt (which works fine for me):

if( substr_count($content, '<div class="myclass') > 1 ) {
    $parts = explode('<div class="myclass',$content);
    echo '<div class="myclass'.$parts[1];
    echo '<div>Check all divs <a href="myurl">here</a></div>';
}
else {echo $content;}
Manticore
  • 1,284
  • 16
  • 38
  • i'm not sure how explode function works, but from documentation it should split a string using delimiter. I guess that would work if applied to the string with div=myclass only, but not to general html structure I have? – Denis Jan 05 '12 at 14:05
  • It surely works but that's only half the code. You have to search for the first closing within that string to get only the div you want and not everthing until the next
    – Manticore Jan 05 '12 at 14:18
  • The only thing worse than [regexen](http://stackoverflow.com/a/1732454/476) for "parsing" HTML is `substr`. Use an X(HT)ML parser! – deceze Jan 05 '12 at 14:25
  • Thanks for your kind reply and you're vote down. I really appreciate it! Makes me want to show more effort than I already did! *ironic off* – Manticore Jan 05 '12 at 14:41
  • 1
    -1 @manticore The problem with regex or substr solutions is that they assume too much about the HTML in the $content string. For example, an inner div will produce an extra closing . Sure you can get round that problem, but DOMDocument (and other parsers) already does the job. (Also -1 for sarcasm. Points are awarded for correctness, not effort.) – Dan Blows Jan 05 '12 at 16:09
  • Okay I understand now. No answering as long as I don't have my master in IT and wrote my doctoral thesis about it. – Manticore Jan 09 '12 at 13:25
  • Then another guy quits SO. – Léon Pelletier May 26 '13 at 17:53