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.