1Mojo::DOM(3)          User Contributed Perl Documentation         Mojo::DOM(3)
2
3
4

NAME

6       Mojo::DOM - Minimalistic HTML/XML DOM parser with CSS selectors
7

SYNOPSIS

9         use Mojo::DOM;
10
11         # Parse
12         my $dom = Mojo::DOM->new('<div><p id="a">Test</p><p id="b">123</p></div>');
13
14         # Find
15         say $dom->at('#b')->text;
16         say $dom->find('p')->map('text')->join("\n");
17         say $dom->find('[id]')->map(attr => 'id')->join("\n");
18
19         # Iterate
20         $dom->find('p[id]')->reverse->each(sub { say $_->{id} });
21
22         # Loop
23         for my $e ($dom->find('p[id]')->each) {
24           say $e->{id}, ':', $e->text;
25         }
26
27         # Modify
28         $dom->find('div p')->last->append('<p id="c">456</p>');
29         $dom->at('#c')->prepend($dom->new_tag('p', id => 'd', '789'));
30         $dom->find(':not(p)')->map('strip');
31
32         # Render
33         say "$dom";
34

DESCRIPTION

36       Mojo::DOM is a minimalistic and relaxed HTML/XML DOM parser with CSS
37       selector support. It will even try to interpret broken HTML and XML, so
38       you should not use it for validation.
39

NODES AND ELEMENTS

41       When we parse an HTML/XML fragment, it gets turned into a tree of
42       nodes.
43
44         <!DOCTYPE html>
45         <html>
46           <head><title>Hello</title></head>
47           <body>World!</body>
48         </html>
49
50       There are currently eight different kinds of nodes, "cdata", "comment",
51       "doctype", "pi", "raw", "root", "tag" and "text". Elements are nodes of
52       the type "tag".
53
54         root
55         |- doctype (html)
56         +- tag (html)
57            |- tag (head)
58            |  +- tag (title)
59            |     +- raw (Hello)
60            +- tag (body)
61               +- text (World!)
62
63       While all node types are represented as Mojo::DOM objects, some methods
64       like "attr" and "namespace" only apply to elements.
65

CASE-SENSITIVITY

67       Mojo::DOM defaults to HTML semantics, that means all tags and attribute
68       names are lowercased and selectors need to be lowercase as well.
69
70         # HTML semantics
71         my $dom = Mojo::DOM->new('<P ID="greeting">Hi!</P>');
72         say $dom->at('p[id]')->text;
73
74       If an XML declaration is found, the parser will automatically switch
75       into XML mode and everything becomes case-sensitive.
76
77         # XML semantics
78         my $dom = Mojo::DOM->new('<?xml version="1.0"?><P ID="greeting">Hi!</P>');
79         say $dom->at('P[ID]')->text;
80
81       HTML or XML semantics can also be forced with the "xml" method.
82
83         # Force HTML semantics
84         my $dom = Mojo::DOM->new->xml(0)->parse('<P ID="greeting">Hi!</P>');
85         say $dom->at('p[id]')->text;
86
87         # Force XML semantics
88         my $dom = Mojo::DOM->new->xml(1)->parse('<P ID="greeting">Hi!</P>');
89         say $dom->at('P[ID]')->text;
90

METHODS

92       Mojo::DOM implements the following methods.
93
94   all_text
95         my $text = $dom->all_text;
96
97       Extract text content from all descendant nodes of this element. For
98       HTML documents "script" and "style" elements are excluded.
99
100         # "foo\nbarbaz\n"
101         $dom->parse("<div>foo\n<p>bar</p>baz\n</div>")->at('div')->all_text;
102
103   ancestors
104         my $collection = $dom->ancestors;
105         my $collection = $dom->ancestors('div ~ p');
106
107       Find all ancestor elements of this node matching the CSS selector and
108       return a Mojo::Collection object containing these elements as Mojo::DOM
109       objects. All selectors from "SELECTORS" in Mojo::DOM::CSS are
110       supported.
111
112         # List tag names of ancestor elements
113         say $dom->ancestors->map('tag')->join("\n");
114
115   append
116         $dom = $dom->append('<p>I ♥ Mojolicious!</p>');
117         $dom = $dom->append(Mojo::DOM->new);
118
119       Append HTML/XML fragment to this node (for all node types other than
120       "root").
121
122         # "<div><h1>Test</h1><h2>123</h2></div>"
123         $dom->parse('<div><h1>Test</h1></div>')
124           ->at('h1')->append('<h2>123</h2>')->root;
125
126         # "<p>Test 123</p>"
127         $dom->parse('<p>Test</p>')->at('p')
128           ->child_nodes->first->append(' 123')->root;
129
130   append_content
131         $dom = $dom->append_content('<p>I ♥ Mojolicious!</p>');
132         $dom = $dom->append_content(Mojo::DOM->new);
133
134       Append HTML/XML fragment (for "root" and "tag" nodes) or raw content to
135       this node's content.
136
137         # "<div><h1>Test123</h1></div>"
138         $dom->parse('<div><h1>Test</h1></div>')
139           ->at('h1')->append_content('123')->root;
140
141         # "<!-- Test 123 --><br>"
142         $dom->parse('<!-- Test --><br>')
143           ->child_nodes->first->append_content('123 ')->root;
144
145         # "<p>Test<i>123</i></p>"
146         $dom->parse('<p>Test</p>')->at('p')->append_content('<i>123</i>')->root;
147
148   at
149         my $result = $dom->at('div ~ p');
150         my $result = $dom->at('svg|line', svg => 'http://www.w3.org/2000/svg');
151
152       Find first descendant element of this element matching the CSS selector
153       and return it as a Mojo::DOM object, or "undef" if none could be found.
154       All selectors from "SELECTORS" in Mojo::DOM::CSS are supported.
155
156         # Find first element with "svg" namespace definition
157         my $namespace = $dom->at('[xmlns\:svg]')->{'xmlns:svg'};
158
159       Trailing key/value pairs can be used to declare xml namespace aliases.
160
161         # "<rect />"
162         $dom->parse('<svg xmlns="http://www.w3.org/2000/svg"><rect /></svg>')
163           ->at('svg|rect', svg => 'http://www.w3.org/2000/svg');
164
165   attr
166         my $hash = $dom->attr;
167         my $foo  = $dom->attr('foo');
168         $dom     = $dom->attr({foo => 'bar'});
169         $dom     = $dom->attr(foo => 'bar');
170
171       This element's attributes.
172
173         # Remove an attribute
174         delete $dom->attr->{id};
175
176         # Attribute without value
177         $dom->attr(selected => undef);
178
179         # List id attributes
180         say $dom->find('*')->map(attr => 'id')->compact->join("\n");
181
182   child_nodes
183         my $collection = $dom->child_nodes;
184
185       Return a Mojo::Collection object containing all child nodes of this
186       element as Mojo::DOM objects.
187
188         # "<p><b>123</b></p>"
189         $dom->parse('<p>Test<b>123</b></p>')->at('p')->child_nodes->first->remove;
190
191         # "<!DOCTYPE html>"
192         $dom->parse('<!DOCTYPE html><b>123</b>')->child_nodes->first;
193
194         # " Test "
195         $dom->parse('<b>123</b><!-- Test -->')->child_nodes->last->content;
196
197   children
198         my $collection = $dom->children;
199         my $collection = $dom->children('div ~ p');
200
201       Find all child elements of this element matching the CSS selector and
202       return a Mojo::Collection object containing these elements as Mojo::DOM
203       objects. All selectors from "SELECTORS" in Mojo::DOM::CSS are
204       supported.
205
206         # Show tag name of random child element
207         say $dom->children->shuffle->first->tag;
208
209   content
210         my $str = $dom->content;
211         $dom    = $dom->content('<p>I ♥ Mojolicious!</p>');
212         $dom    = $dom->content(Mojo::DOM->new);
213
214       Return this node's content or replace it with HTML/XML fragment (for
215       "root" and "tag" nodes) or raw content.
216
217         # "<b>Test</b>"
218         $dom->parse('<div><b>Test</b></div>')->at('div')->content;
219
220         # "<div><h1>123</h1></div>"
221         $dom->parse('<div><h1>Test</h1></div>')->at('h1')->content('123')->root;
222
223         # "<p><i>123</i></p>"
224         $dom->parse('<p>Test</p>')->at('p')->content('<i>123</i>')->root;
225
226         # "<div><h1></h1></div>"
227         $dom->parse('<div><h1>Test</h1></div>')->at('h1')->content('')->root;
228
229         # " Test "
230         $dom->parse('<!-- Test --><br>')->child_nodes->first->content;
231
232         # "<div><!-- 123 -->456</div>"
233         $dom->parse('<div><!-- Test -->456</div>')
234           ->at('div')->child_nodes->first->content(' 123 ')->root;
235
236   descendant_nodes
237         my $collection = $dom->descendant_nodes;
238
239       Return a Mojo::Collection object containing all descendant nodes of
240       this element as Mojo::DOM objects.
241
242         # "<p><b>123</b></p>"
243         $dom->parse('<p><!-- Test --><b>123<!-- 456 --></b></p>')
244           ->descendant_nodes->grep(sub { $_->type eq 'comment' })
245           ->map('remove')->first;
246
247         # "<p><b>test</b>test</p>"
248         $dom->parse('<p><b>123</b>456</p>')
249           ->at('p')->descendant_nodes->grep(sub { $_->type eq 'text' })
250           ->map(content => 'test')->first->root;
251
252   find
253         my $collection = $dom->find('div ~ p');
254         my $collection = $dom->find('svg|line', svg => 'http://www.w3.org/2000/svg');
255
256       Find all descendant elements of this element matching the CSS selector
257       and return a Mojo::Collection object containing these elements as
258       Mojo::DOM objects. All selectors from "SELECTORS" in Mojo::DOM::CSS are
259       supported.
260
261         # Find a specific element and extract information
262         my $id = $dom->find('div')->[23]{id};
263
264         # Extract information from multiple elements
265         my @headers = $dom->find('h1, h2, h3')->map('text')->each;
266
267         # Count all the different tags
268         my $hash = $dom->find('*')->reduce(sub { $a->{$b->tag}++; $a }, {});
269
270         # Find elements with a class that contains dots
271         my @divs = $dom->find('div.foo\.bar')->each;
272
273       Trailing key/value pairs can be used to declare xml namespace aliases.
274
275         # "<rect />"
276         $dom->parse('<svg xmlns="http://www.w3.org/2000/svg"><rect /></svg>')
277           ->find('svg|rect', svg => 'http://www.w3.org/2000/svg')->first;
278
279   following
280         my $collection = $dom->following;
281         my $collection = $dom->following('div ~ p');
282
283       Find all sibling elements after this node matching the CSS selector and
284       return a Mojo::Collection object containing these elements as Mojo::DOM
285       objects. All selectors from "SELECTORS" in Mojo::DOM::CSS are
286       supported.
287
288         # List tags of sibling elements after this node
289         say $dom->following->map('tag')->join("\n");
290
291   following_nodes
292         my $collection = $dom->following_nodes;
293
294       Return a Mojo::Collection object containing all sibling nodes after
295       this node as Mojo::DOM objects.
296
297         # "C"
298         $dom->parse('<p>A</p><!-- B -->C')->at('p')->following_nodes->last->content;
299
300   matches
301         my $bool = $dom->matches('div ~ p');
302         my $bool = $dom->matches('svg|line', svg => 'http://www.w3.org/2000/svg');
303
304       Check if this element matches the CSS selector. All selectors from
305       "SELECTORS" in Mojo::DOM::CSS are supported.
306
307         # True
308         $dom->parse('<p class="a">A</p>')->at('p')->matches('.a');
309         $dom->parse('<p class="a">A</p>')->at('p')->matches('p[class]');
310
311         # False
312         $dom->parse('<p class="a">A</p>')->at('p')->matches('.b');
313         $dom->parse('<p class="a">A</p>')->at('p')->matches('p[id]');
314
315       Trailing key/value pairs can be used to declare xml namespace aliases.
316
317         # True
318         $dom->parse('<svg xmlns="http://www.w3.org/2000/svg"><rect /></svg>')
319           ->matches('svg|rect', svg => 'http://www.w3.org/2000/svg');
320
321   namespace
322         my $namespace = $dom->namespace;
323
324       Find this element's namespace, or return "undef" if none could be
325       found.
326
327         # "http://www.w3.org/2000/svg"
328         Mojo::DOM->new('<svg xmlns:svg="http://www.w3.org/2000/svg"><svg:circle>3.14</svg:circle></svg>')->at('svg\:circle')->namespace;
329
330         # Find namespace for an element with namespace prefix
331         my $namespace = $dom->at('svg > svg\:circle')->namespace;
332
333         # Find namespace for an element that may or may not have a namespace prefix
334         my $namespace = $dom->at('svg > circle')->namespace;
335
336   new
337         my $dom = Mojo::DOM->new;
338         my $dom = Mojo::DOM->new('<foo bar="baz">I ♥ Mojolicious!</foo>');
339
340       Construct a new scalar-based Mojo::DOM object and "parse" HTML/XML
341       fragment if necessary.
342
343   new_tag
344         my $tag = Mojo::DOM->new_tag('div');
345         my $tag = $dom->new_tag('div');
346         my $tag = $dom->new_tag('div', id => 'foo', hidden => undef);
347         my $tag = $dom->new_tag('div', 'safe content');
348         my $tag = $dom->new_tag('div', id => 'foo', 'safe content');
349         my $tag = $dom->new_tag('div', data => {mojo => 'rocks'}, 'safe content');
350         my $tag = $dom->new_tag('div', id => 'foo', sub { 'unsafe content' });
351
352       Construct a new Mojo::DOM object for an HTML/XML tag with or without
353       attributes and content. The "data" attribute may contain a hash
354       reference with key/value pairs to generate attributes from.
355
356         # "<br>"
357         $dom->new_tag('br');
358
359         # "<div></div>"
360         $dom->new_tag('div');
361
362         # "<div id="foo" hidden></div>"
363         $dom->new_tag('div', id => 'foo', hidden => undef);
364
365         # "<div>test &amp; 123</div>"
366         $dom->new_tag('div', 'test & 123');
367
368         # "<div id="foo">test &amp; 123</div>"
369         $dom->new_tag('div', id => 'foo', 'test & 123');
370
371         # "<div data-foo="1" data-bar="test">test &amp; 123</div>""
372         $dom->new_tag('div', data => {foo => 1, Bar => 'test'}, 'test & 123');
373
374         # "<div id="foo">test & 123</div>"
375         $dom->new_tag('div', id => 'foo', sub { 'test & 123' });
376
377         # "<div>Hello<b>Mojo!</b></div>"
378         $dom->parse('<div>Hello</div>')->at('div')
379           ->append_content($dom->new_tag('b', 'Mojo!'))->root;
380
381   next
382         my $sibling = $dom->next;
383
384       Return Mojo::DOM object for next sibling element, or "undef" if there
385       are no more siblings.
386
387         # "<h2>123</h2>"
388         $dom->parse('<div><h1>Test</h1><h2>123</h2></div>')->at('h1')->next;
389
390   next_node
391         my $sibling = $dom->next_node;
392
393       Return Mojo::DOM object for next sibling node, or "undef" if there are
394       no more siblings.
395
396         # "456"
397         $dom->parse('<p><b>123</b><!-- Test -->456</p>')
398           ->at('b')->next_node->next_node;
399
400         # " Test "
401         $dom->parse('<p><b>123</b><!-- Test -->456</p>')
402           ->at('b')->next_node->content;
403
404   parent
405         my $parent = $dom->parent;
406
407       Return Mojo::DOM object for parent of this node, or "undef" if this
408       node has no parent.
409
410         # "<b><i>Test</i></b>"
411         $dom->parse('<p><b><i>Test</i></b></p>')->at('i')->parent;
412
413   parse
414         $dom = $dom->parse('<foo bar="baz">I ♥ Mojolicious!</foo>');
415
416       Parse HTML/XML fragment with Mojo::DOM::HTML.
417
418         # Parse XML
419         my $dom = Mojo::DOM->new->xml(1)->parse('<foo>I ♥ Mojolicious!</foo>');
420
421   preceding
422         my $collection = $dom->preceding;
423         my $collection = $dom->preceding('div ~ p');
424
425       Find all sibling elements before this node matching the CSS selector
426       and return a Mojo::Collection object containing these elements as
427       Mojo::DOM objects. All selectors from "SELECTORS" in Mojo::DOM::CSS are
428       supported.
429
430         # List tags of sibling elements before this node
431         say $dom->preceding->map('tag')->join("\n");
432
433   preceding_nodes
434         my $collection = $dom->preceding_nodes;
435
436       Return a Mojo::Collection object containing all sibling nodes before
437       this node as Mojo::DOM objects.
438
439         # "A"
440         $dom->parse('A<!-- B --><p>C</p>')->at('p')->preceding_nodes->first->content;
441
442   prepend
443         $dom = $dom->prepend('<p>I ♥ Mojolicious!</p>');
444         $dom = $dom->prepend(Mojo::DOM->new);
445
446       Prepend HTML/XML fragment to this node (for all node types other than
447       "root").
448
449         # "<div><h1>Test</h1><h2>123</h2></div>"
450         $dom->parse('<div><h2>123</h2></div>')
451           ->at('h2')->prepend('<h1>Test</h1>')->root;
452
453         # "<p>Test 123</p>"
454         $dom->parse('<p>123</p>')
455           ->at('p')->child_nodes->first->prepend('Test ')->root;
456
457   prepend_content
458         $dom = $dom->prepend_content('<p>I ♥ Mojolicious!</p>');
459         $dom = $dom->prepend_content(Mojo::DOM->new);
460
461       Prepend HTML/XML fragment (for "root" and "tag" nodes) or raw content
462       to this node's content.
463
464         # "<div><h2>Test123</h2></div>"
465         $dom->parse('<div><h2>123</h2></div>')
466           ->at('h2')->prepend_content('Test')->root;
467
468         # "<!-- Test 123 --><br>"
469         $dom->parse('<!-- 123 --><br>')
470           ->child_nodes->first->prepend_content(' Test')->root;
471
472         # "<p><i>123</i>Test</p>"
473         $dom->parse('<p>Test</p>')->at('p')->prepend_content('<i>123</i>')->root;
474
475   previous
476         my $sibling = $dom->previous;
477
478       Return Mojo::DOM object for previous sibling element, or "undef" if
479       there are no more siblings.
480
481         # "<h1>Test</h1>"
482         $dom->parse('<div><h1>Test</h1><h2>123</h2></div>')->at('h2')->previous;
483
484   previous_node
485         my $sibling = $dom->previous_node;
486
487       Return Mojo::DOM object for previous sibling node, or "undef" if there
488       are no more siblings.
489
490         # "123"
491         $dom->parse('<p>123<!-- Test --><b>456</b></p>')
492           ->at('b')->previous_node->previous_node;
493
494         # " Test "
495         $dom->parse('<p>123<!-- Test --><b>456</b></p>')
496           ->at('b')->previous_node->content;
497
498   remove
499         my $parent = $dom->remove;
500
501       Remove this node and return "root" (for "root" nodes) or "parent".
502
503         # "<div></div>"
504         $dom->parse('<div><h1>Test</h1></div>')->at('h1')->remove;
505
506         # "<p><b>456</b></p>"
507         $dom->parse('<p>123<b>456</b></p>')
508           ->at('p')->child_nodes->first->remove->root;
509
510   replace
511         my $parent = $dom->replace('<div>I ♥ Mojolicious!</div>');
512         my $parent = $dom->replace(Mojo::DOM->new);
513
514       Replace this node with HTML/XML fragment and return "root" (for "root"
515       nodes) or "parent".
516
517         # "<div><h2>123</h2></div>"
518         $dom->parse('<div><h1>Test</h1></div>')->at('h1')->replace('<h2>123</h2>');
519
520         # "<p><b>123</b></p>"
521         $dom->parse('<p>Test</p>')
522           ->at('p')->child_nodes->[0]->replace('<b>123</b>')->root;
523
524   root
525         my $root = $dom->root;
526
527       Return Mojo::DOM object for "root" node.
528
529   selector
530         my $selector = $dom->selector;
531
532       Get a unique CSS selector for this element.
533
534         # "ul:nth-child(1) > li:nth-child(2)"
535         $dom->parse('<ul><li>Test</li><li>123</li></ul>')->find('li')->last->selector;
536
537         # "p:nth-child(1) > b:nth-child(1) > i:nth-child(1)"
538         $dom->parse('<p><b><i>Test</i></b></p>')->at('i')->selector;
539
540   strip
541         my $parent = $dom->strip;
542
543       Remove this element while preserving its content and return "parent".
544
545         # "<div>Test</div>"
546         $dom->parse('<div><h1>Test</h1></div>')->at('h1')->strip;
547
548   tag
549         my $tag = $dom->tag;
550         $dom    = $dom->tag('div');
551
552       This element's tag name.
553
554         # List tag names of child elements
555         say $dom->children->map('tag')->join("\n");
556
557   tap
558         $dom = $dom->tap(sub {...});
559
560       Alias for "tap" in Mojo::Base.
561
562   text
563         my $text = $dom->text;
564
565       Extract text content from this element only (not including child
566       elements).
567
568         # "bar"
569         $dom->parse("<div>foo<p>bar</p>baz</div>")->at('p')->text;
570
571         # "foo\nbaz\n"
572         $dom->parse("<div>foo\n<p>bar</p>baz\n</div>")->at('div')->text;
573
574       To extract text content from all descendant nodes see "all_text".
575
576   to_string
577         my $str = $dom->to_string;
578
579       Render this node and its content to HTML/XML.
580
581         # "<b>Test</b>"
582         $dom->parse('<div><b>Test</b></div>')->at('div b')->to_string;
583
584   tree
585         my $tree = $dom->tree;
586         $dom     = $dom->tree(['root']);
587
588       Document Object Model. Note that this structure should only be used
589       very carefully since it is very dynamic.
590
591   type
592         my $type = $dom->type;
593
594       This node's type, usually "cdata", "comment", "doctype", "pi", "raw",
595       "root", "tag" or "text".
596
597         # "cdata"
598         $dom->parse('<![CDATA[Test]]>')->child_nodes->first->type;
599
600         # "comment"
601         $dom->parse('<!-- Test -->')->child_nodes->first->type;
602
603         # "doctype"
604         $dom->parse('<!DOCTYPE html>')->child_nodes->first->type;
605
606         # "pi"
607         $dom->parse('<?xml version="1.0"?>')->child_nodes->first->type;
608
609         # "raw"
610         $dom->parse('<title>Test</title>')->at('title')->child_nodes->first->type;
611
612         # "root"
613         $dom->parse('<p>Test</p>')->type;
614
615         # "tag"
616         $dom->parse('<p>Test</p>')->at('p')->type;
617
618         # "text"
619         $dom->parse('<p>Test</p>')->at('p')->child_nodes->first->type;
620
621   val
622         my $value = $dom->val;
623
624       Extract value from form element (such as "button", "input", "option",
625       "select" and "textarea"), or return "undef" if this element has no
626       value. In the case of "select" with "multiple" attribute, find "option"
627       elements with "selected" attribute and return an array reference with
628       all values, or "undef" if none could be found.
629
630         # "a"
631         $dom->parse('<input name=test value=a>')->at('input')->val;
632
633         # "b"
634         $dom->parse('<textarea>b</textarea>')->at('textarea')->val;
635
636         # "c"
637         $dom->parse('<option value="c">Test</option>')->at('option')->val;
638
639         # "d"
640         $dom->parse('<select><option selected>d</option></select>')
641           ->at('select')->val;
642
643         # "e"
644         $dom->parse('<select multiple><option selected>e</option></select>')
645           ->at('select')->val->[0];
646
647         # "on"
648         $dom->parse('<input name=test type=checkbox>')->at('input')->val;
649
650   with_roles
651         my $new_class = Mojo::DOM->with_roles('Mojo::DOM::Role::One');
652         my $new_class = Mojo::DOM->with_roles('+One', '+Two');
653         $dom          = $dom->with_roles('+One', '+Two');
654
655       Alias for "with_roles" in Mojo::Base.
656
657   wrap
658         $dom = $dom->wrap('<div></div>');
659         $dom = $dom->wrap(Mojo::DOM->new);
660
661       Wrap HTML/XML fragment around this node (for all node types other than
662       "root"), placing it as the last child of the first innermost element.
663
664         # "<p>123<b>Test</b></p>"
665         $dom->parse('<b>Test</b>')->at('b')->wrap('<p>123</p>')->root;
666
667         # "<div><p><b>Test</b></p>123</div>"
668         $dom->parse('<b>Test</b>')->at('b')->wrap('<div><p></p>123</div>')->root;
669
670         # "<p><b>Test</b></p><p>123</p>"
671         $dom->parse('<b>Test</b>')->at('b')->wrap('<p></p><p>123</p>')->root;
672
673         # "<p><b>Test</b></p>"
674         $dom->parse('<p>Test</p>')->at('p')->child_nodes->first->wrap('<b>')->root;
675
676   wrap_content
677         $dom = $dom->wrap_content('<div></div>');
678         $dom = $dom->wrap_content(Mojo::DOM->new);
679
680       Wrap HTML/XML fragment around this node's content (for "root" and "tag"
681       nodes), placing it as the last children of the first innermost element.
682
683         # "<p><b>123Test</b></p>"
684         $dom->parse('<p>Test<p>')->at('p')->wrap_content('<b>123</b>')->root;
685
686         # "<p><b>Test</b></p><p>123</p>"
687         $dom->parse('<b>Test</b>')->wrap_content('<p></p><p>123</p>');
688
689   xml
690         my $bool = $dom->xml;
691         $dom     = $dom->xml($bool);
692
693       Disable HTML semantics in parser and activate case-sensitivity,
694       defaults to auto-detection based on XML declarations.
695

OPERATORS

697       Mojo::DOM overloads the following operators.
698
699   array
700         my @nodes = @$dom;
701
702       Alias for "child_nodes".
703
704         # "<!-- Test -->"
705         $dom->parse('<!-- Test --><b>123</b>')->[0];
706
707   bool
708         my $bool = !!$dom;
709
710       Always true.
711
712   hash
713         my %attrs = %$dom;
714
715       Alias for "attr".
716
717         # "test"
718         $dom->parse('<div id="test">Test</div>')->at('div')->{id};
719
720   stringify
721         my $str = "$dom";
722
723       Alias for "to_string".
724

SEE ALSO

726       Mojolicious, Mojolicious::Guides, <https://mojolicious.org>.
727
728
729
730perl v5.34.0                      2022-01-21                      Mojo::DOM(3)
Impressum