how to add a xml node to a symfony Crawler()
Asked Answered
E

1

7

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

Expect answered 29/11, 2016 at 9:36 Comment(0)
S
2

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.

Sellers answered 17/1, 2018 at 21:56 Comment(2)
thank you for your response. I forgot for which project i had this problem, i solved it but i don't remember how. I remember that the code was clean and i think it was something almost similar than your code. Sorry it's been a long time and i've got memory problem in my brain, trying to allocate xxxx KoExpect
@VanIllaSkyPEPaPaCinO no worries, ha it'd be great if you could find your solution so I could compare it to mine!Sellers

© 2022 - 2024 — McMap. All rights reserved.