Search code examples
perlmojolicious

Replacing XML nodes using perl and Mojo::DOM


I would like to exchange node in an XML file using Mojo::DOM. I'm pretty sure it is possible but I didn't find a way yet.

Given the following XML:

my $xml = q~
<html>
    <div>
        <p>1</p>
        <p>2</p>
        <img />
    </div>
</html>
~;

I would like to remove the div and instead insert a body tag, so that the result looks like this:

my $xml = q~
<html>
    <body>
        <p>1</p>
        <p>2</p>
        <img />
    </body>
</html>
~;

I thought about replace, but I didn't find an example where the replacement is the $dom of the replaced tag.


Solution

  • It's very simple to just find the <div> element and use the tag method to change its tag

    This program demonstrates. The CSS selector html > div finds the (first) <div> element that is a child of an <html> element

    use strict;
    use warnings;
    
    use Mojo::DOM;
    
    my $xml = q~
    <html>
        <div>
            <p>1</p>
            <p>2</p>
            <img />
        </div>
    </html>
    ~;
    
    my $dom = Mojo::DOM->new($xml);
    
    $dom->at('html > div')->tag('body');
    
    print $dom, "\n";
    

    output

        <html>
            <body>
                <p>1</p>
                <p>2</p>
                <img>
            </body>
        </html>