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

OPERATORS

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

SEE ALSO

722       Mojolicious, Mojolicious::Guides, <https://mojolicious.org>.
723
724
725
726perl v5.32.0                      2020-07-28                      Mojo::DOM(3)
Impressum