1Mojo::DOM(3) User Contributed Perl Documentation Mojo::DOM(3)
2
3
4
6 Mojo::DOM - Minimalistic HTML/XML DOM parser with CSS selectors
7
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
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
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
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
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 & 123</div>"
362 $dom->new_tag('div', 'test & 123');
363
364 # "<div id="foo">test & 123</div>"
365 $dom->new_tag('div', id => 'foo', 'test & 123');
366
367 # "<div data-foo="1" data-bar="test">test & 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
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
722 Mojolicious, Mojolicious::Guides, <https://mojolicious.org>.
723
724
725
726perl v5.32.0 2020-07-28 Mojo::DOM(3)