tags:

views:

62

answers:

4

I want to replace all <span> tags with <p> using phpquery. What is wrong with my code? It finds the span but the replaceWith function is not doing anything.

$event = phpQuery::newDocumentHTML(file_get_contents('event.html'));
$formatted_event = $event->find('span')->replaceWith('<p>');

This documentation indicates this is possible:
http://code.google.com/p/phpquery/wiki/Manipulation#Replacing
http://api.jquery.com/replaceWith/

This is the html that gets returned with and without ->replaceWith('<p></p>') in the code:

<span class="Subhead1">Event 1<br></span><span class="Subhead2">Event 2<br>
    August 12, 2010<br>
    2:35pm <br>
    Free</span>
+1  A: 

Try;

$formatted_event = $event->find('span')->replaceWith('<p></p>');
karim79
I'm assuming op is looking to turn all of the spans into paragraphs but keeping content?
Andrei Serdeliuc
Yes wanting to keep the content. I thought using ->replaceWith('<p></p>') would work also, but replaceWith just seems to do nothing. I'm not getting any errors from phpquery. I edited my post to show the html I'm trying to change.
JMC
A: 

Did you try:

 $formatted_event = $event->find('span')->replaceWith('p');
shamittomar
+1  A: 

Wont str_replace do a better job at this? Its faster and easier to debug. Always take into consideration that external libraries may have bugs:)

$htmlContent = str_replace("<span", "<p", $htmlContent);
$htmlContent = str_replace("</span>", "</p>", $htmlContent);    
Quamis
+1 - If by faster and easier, you mean, not wasting 3 hours trying to make phpquery do what I already knew how to do, then you are correct Sir! :) The idea of phpquery / jquery performing manipulation tasks is appealing since it should be easy to string manipulation functions together. When it doesn't work, it is a pain. I'm probably using the wrong syntax for the phpquery manipulation functions, because none of them seem to work. All the traverse functions work like magic.
JMC
+1  A: 

If you dont mind a plain DOMDocument solution (DOMDocument is used unter the hood of phpQuery to parse the HTML fragments), I did something similiar a while ago. I adapted the code to do what you need:

$document = new DOMDocument();

// load html from file
$document->loadHTMLFile('event.html');

// find all span elements in document
$spanElements = $document->getElementsByTagname('span');
$spanElementsToReplace = array();

// use temp array to store span elements
// as you cant iterate a NodeList and replace the nodes
foreach($spanElements as $spanElement) {
  $spanElementsToReplace[] = $spanElement;
}

// create a p element, append the children of the span to the p element, 
// replace span element with p element
foreach($spanElementsToReplace as $spanElement) {
    $p = $document->createElement('p');

    foreach($spanElement->childNodes as $child) {
        $p->appendChild($child->cloneNode(true));
    }

    $spanElement->parentNode->replaceChild($p, $spanElement);
} 

// print innerHTML of body element
print DOMinnerHTML($document->getElementsByTagName('body')->item(0));


// --------------------------------


// Utility function to get innerHTML of an element
// -> "stolen" from: http://www.php.net/manual/de/book.dom.php#89718
function DOMinnerHTML($element) {
    $innerHTML = "";
    $children = $element->childNodes;
    foreach ($children as $child)
    {
        $tmp_dom = new DOMDocument();
        $tmp_dom->appendChild($tmp_dom->importNode($child, true));
        $innerHTML.=trim($tmp_dom->saveHTML());
    }
    return $innerHTML;
} 

Maybe this can get you in the right direction on how to do the replacement in phpQuery?


EDIT:

I gave the jQuery documentation of replaceWith another look, it seems to me, that you have to pass in the whole html fragment which you want to be your new, replaced content.

This code snipped worked for me:

$event = phpQuery::newDocumentHTML(...);

// iterate over the spans
foreach($event->find('span') as $span) {
// make $span a phpQuery object, otherwise its just a DOMElement object
$span = pq($span);
// fetch the innerHTMLL of the span, and replace the span with <p>
$span->replaceWith('<p>' . $span->html() . '</p>');
}

print (string) $event;

I couldnt find any way to do this with chained method calls in one line.

Max
+1 - Thanks a lot for posting this. Going to play around with it. This is written well and easily to read. Will make a great launching point for learning how phpquery is manipulating. Blackboxes are only good until they don't work :).I would still like to know why manipulation in phpquery isn't working from my code. I was hoping someone familiar with phpquery could validate if my query: $formatted_event = $event->find('span')->replaceWith('<p></p>'); is written correctly and works.
JMC
@acidjazz thanks! I gave it another try with phpQuery, please see my edit. :-)
Max
@Max - This is perfect. It returned the magic to phpquery :). Using the pq() function was what had me hung up. This code works also: $span = pq($event->find('span')) ; $span->replaceWith('<p>' . $span->html() . '</p>');Just takes the foreach out of the picture. Thanks!
JMC