2

I would like to parse a DOM and find a particular node from a data attribute name. Then I would like to replace it by an another dom.

I success to find the DOM nodes but I have some difficulties to replace it. Here my code:

$content = '<article class="post-35">
            <div class="inner">
                <div class="holder dark">
                    <div class="media"></div>
                    <i class="icon-play"></i>
                    <i class="icon-link"></i>
                </div>
                <span class="item-date">July 3, 2015</span>
                <h2 class="item-title"><a href="">A title</a></h2>
                <span class="post-like" data-post-id="35" >
                    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 64 64"><g><path></path></g></svg>
                    <span class="like-count">2</span>
                </span>
            </div>
        </article>

        <article class="post-36">
            <div class="inner">
                <div class="holder dark">
                    <div class="media"></div>
                    <i class="icon-play"></i>
                    <i class="icon-link"></i>
                </div>
                <span class="item-date">July 3, 2015</span>
                <h2 class="item-title"><a href="">A title</a></h2>
                <span class="post-like" data-post-id="36" >
                    <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 64 64"><g><path></path></g></svg>
                    <span class="like-count">5</span>
                </span>
            </div>
        </article>';

$dom = new DOMDocument();
@$dom->loadHTML($content);
$finder = new DOMXPath($dom);
$nodes  = $finder->query('//span[@data-post-id]/@data-post-id');
foreach ($nodes as $node) {
    $like = post_like($node->value); // '<span class="my-class"><svg></svg><span>xx</span>'
    $like = $dom->createElement('span',$like);
    //$node->parentNode->parentNode->appendChild($like); // this works but append plain text not html...
    $node->parentNode->replaceChild($like, $node); // fatal error Uncaught exception 'DOMException' with message 'Not Found Error' 
}

What is wrong?

EDIT:

When I print_r node I've got this:

DOMAttr Object
(
    [name] => post-id
    [specified] => 1
    [value] => 35
    [ownerElement] => (object value omitted)
    [schemaTypeInfo] => 
    [nodeName] => post-id
    [nodeValue] => 35
    [nodeType] => 2
    [parentNode] => (object value omitted)
    [childNodes] => (object value omitted)
    [firstChild] => (object value omitted)
    [lastChild] => (object value omitted)
    [previousSibling] => (object value omitted)
    [nextSibling] => (object value omitted)
    [attributes] => 
    [ownerDocument] => (object value omitted)
    [namespaceURI] => 
    [prefix] => 
    [localName] => post-id
    [baseURI] => 
    [textContent] => 35
)
8
  • 1
    What are the difficulties you are mentionning ? Do you have any error message ? Any other visual manifestation of the problem ? Commented Aug 18, 2015 at 15:21
  • I've got an error on replacechild line. I have add the error in comment. Commented Aug 18, 2015 at 15:23
  • Well, it pays of to read the error messages: Wrong Document Error. You create a new node in a different DOMDocument, so you can't insert it into the previous one. Commented Aug 18, 2015 at 15:27
  • With the same dom I've got this error: Uncaught exception 'DOMException' with message 'Not Found Error' Commented Aug 18, 2015 at 15:42
  • Can you post a bit more of the HTML part? And maybe post_like()? Commented Aug 18, 2015 at 18:32

2 Answers 2

1

You can use the DOMDocumentFragment appendXML method to add a "string" of nodes correctly to an existing DOM.

foreach ($nodes as $node) {
    $like = post_like($node->value);
    $frag = $dom->createDocumentFragment();
    $frag->appendXML("<span>" . $like . "</span>");
    $node->parentNode->parentNode->appendChild($frag);
}
Sign up to request clarification or add additional context in comments.

Comments

0

I think you should use the same document to create your element:

$content = '<div>.....</div>';
$dom = new DOMDocument();
@$dom->loadHTML($content);
$finder = new DOMXPath($dom);
$nodes  = $finder->query('//span[@data-post-id]/@data-post-id');
foreach ($nodes as $node) {
    $like = post_like($node->value); // return html string (<span>...</span>)
    $like = $dom->createElement('span',$like);
    $node->parentNode->replaceChild($like, $node);
}

2 Comments

Thank you for your answer. it was my first try but I have an error with your code: Uncaught exception 'DOMException' with message 'Not Found Error'...
I edited my question and add a print of the node inside the foreach loop. It seems that the parentNode is missing but I don't know why...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.