Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to add a xml node to a symfony Crawler()

I need to manage xml documents in saymfony.

I've got no problem to get the xml into a Crawler() instance, modify existing node and after it, put the xml into a file.

But i can't add new node.

When i try to add a new node with appendChild method to the parent, i've got:

wrong document error

And when i try the add method to the crawler, i've got:

impossible to add two differents sources to the crawler?

What can i do to add a simple node to an existing crawler?

Thanks for any response

like image 956
Jul6art Avatar asked Nov 29 '16 09:11

Jul6art


1 Answers

I had a similar issue to you, I tried:

$crawler=new Crawler($someHtml);
$crawler->add('<element />');

and got

Attaching DOM nodes from multiple documents in the same crawler is forbidden.

With a DOMDocument, you use its own createElement method to make node(s), and then attach them to the document with appendChild or whatever. But since Crawler doesn't seem to have anything like createElement, the solution I came up with is to initialize the Crawler with a native dom document, do whatever you want to do with the Crawler, but then use the dom document as a "node factory" when you need to add a node.

My particular situation was that I need to check if a document had a head, and add one (specifically add it above the body tag) if it didn't:

        $doc = new \DOMDocument;
        $doc->loadHtml("<html><body bgcolor='red' /></html>");
        $crawler = new Crawler($doc);
        if ($crawler->filter('head')->count() == 0) {
            //use native dom document to make a head
            $head = $doc->createElement('head');
            //add it to the bottom of the Crawler's node list
            $crawler->add($head);
            //grab the body
            $body = $crawler
                ->filter('body')
                ->first()
                ->getNode(0);
            //use insertBefore (http://php.net/manual/en/domnode.insertbefore.php)
            //to get the head and put it above the body
            $body->parentNode->insertBefore($head, $body);
        }

echo $crawler->html();

yields

<head></head>
<body bgcolor="red"></body>

It seems a little convoluted but it works. I'm dealing with HTML but I imagine an XML solution would be nearly the same.

like image 144
chiliNUT Avatar answered Oct 16 '22 07:10

chiliNUT