XML::Pa...e::ETree(3)

πŸ“¦ version 0.09, in alpine 3.24

πŸ¦‹ XML::Parser::Style::ETree β€” the Perl doc page, but make it make sense πŸ¦‹

okay so bestie, this is a page from the User Contributed Perl Documentation set β€” it's XML::Parser::Style::ETree, and it's basically the moment XML turns into a cute little Perl hash for you. no cap, it's giving "tree but make it data structure" πŸ’…


✨ NAME ✨

XML::Parser::Style::ETree β€” parse xml to simple tree. that's it, that's the whole vibe πŸŽ€


🌸 VERSION 🌸

Version 0.09 β€” yes queen, we're on 0.09 πŸ’–


🧚 SYNOPSIS 🧚

the whole setup is literally two lines:

use XML::Parser;
my $p = XML::Parser->new( Style => 'ETree' );

that's the entire ritual. slay ✨


πŸ“ EXAMPLE πŸ“

okay so imagine this lil XML:

<root at="key">
        <nest>
                first
                <v>a</v>
                mid
                <v at="a">b</v>
                <vv></vv>
                last
        </nest>
</root>

it will be β€” and honestly this is iconic β€”

{
        root => {
                '-at' => 'key',
                nest => {
                        '#text' => 'firstmidlast',
                        vv => '',
                        v => [
                                'a',
                                {
                                        '-at' => 'a',
                                        '#text' => 'b'
                                }
                        ]
                }
        }
}

see how the text got all smooshed together into '#text' => 'firstmidlast'? that's not a bug bestie, that's the whole point 🫢


πŸ‘‘ SPECIAL VARIABLES πŸ‘‘

these are the knobs you can turn. global package variables, main character energy, handle with care πŸ’œ

πŸ’… $TEXT{ATTR} [ = '-' ]

lets you set the prefix for the name of attribute nodes, periodt.

<item attr="value" />
# will be
item => { -attr => 'value' };

# with
$TEXT{ATTR} = '+';
# will be
item => { '+attr' => 'value' };

lowkey obsessed with how easy that is ✨

πŸŽ€ $TEXT{NODE} [ = '#text' ]

lets you set the name for text nodes, bestie.

<item><sub attr="t"></sub>Text value</item>
# will be
item => { sub => { -attr => "t" }, #text => 'Text value' };

# with
$TEXT{NODE} = '';
# will be
item => { sub => { -attr => "t" }, '' => 'Text value' };

set it to the empty string and your text node key is just… nothing. iykyk πŸ™ˆ

⭐ $TEXT{JOIN} [ = '' ]

lets you set the join separator for a text node that got split up by subnodes. (yes, "splitted" β€” the original said splitted, and we respect the original πŸ’€)

<item>Test1<sub />Test2</item>
# will be
item => { sub => '', #text => 'Test1Test2' };

# with
$TEXT{JOIN} = '+';
# will be
item => { sub => '', #text => 'Test1+Test2' };

🌈 $TEXT{TRIM} [ = 1 ]

trims leading and trailing whitespace from text nodes. it's on by default, and honestly it's doing the lord's work πŸ’–

<item>  Test1  <sub />  Test2  </item>
# will be
item => { sub => '', #text => 'Test1Test2' };

# with
$TEXT{TRIM} = 0;
# will be
item => { sub => '', #text => '  Test1    Test2  ' };

πŸ”₯ %FORCE_ARRAY

lets you force nodes to always be represented as arrays. if the name is the empty string, that means ALL. (the original typo'd it as "ot" β€” we love a lil chaos 🫢)

<item><sub attr="t"></sub>Text value</item>

# will be
item => { sub => { -attr => "t" }, #text => 'Text value' };

# with
$FORCE_ARRAY{sub} = 1;
# will be
item => { sub => [ { -attr => "t" } ], #text => 'Text value' };

# with
$FORCE_ARRAY{''} = 1;
# will be
item => [ { sub => [ { -attr => "t" } ], #text => 'Text value' } ];

not me looking at that last one like πŸ‘οΈπŸ‘„πŸ‘οΈ β€” yeah it wraps the whole item in an array. that's ALL doing its thing.

πŸ’€ %FORCE_HASH

lets you force text-only nodes to always be represented as hashes. if the name is the empty string, again, that means ALL.

<item><sub>Text value</sub><any>Text value</any></item>

# will be
item => { sub => 'Text value', any => 'Text value' };

# with
$FORCE_HASH{sub} = 1;
# will be
item => { sub => { #text => 'Text value' }, any => 'Text value' };

# with
$FORCE_HASH{''} = 1;
# will be
item => { sub => { #text => 'Text value' }, any => { #text => 'Text value' } };

consistent output shapes are highkey underrated, fr fr πŸ’œ

🌟 @STRIP_KEY

lets you strip stuff from tag names using regular expressions. yes, regex. buckle up ✨

<a:item><b:sub>Text value</b:sub></a:item>

# will be
'a:item' => { 'b:sub' => 'Text value' };

# with
@STRIP_KEY = (qr/^[^:]+:/);
# will be
'item' => { 'sub' => 'Text value' };

goodbye namespaces, hello clean keys πŸŽ€ (it's an array, so you can stack multiple patterns β€” the original just shows one, and we're not gonna invent more πŸ‘‘)


🧚 SEE ALSO 🧚

the friends of this module, in order, with all the commentary πŸ’–

  • XML::Parser β€” the parser itself. the parent. the main character.
  • XML::Parser::EasyTree β€” another EasyTree. the author says (and i quote in spirit) they didn't find it before their first commit of this package, because of the missing '::Style' in its name 😭 so, since XML::Parser::EasyTree and XML::Parser::Style::EasyTree use the same style name, they're mutually exclusive ;( β€” you can't have both, bestie, pick a lane. so all the functionality was moved to ETree, and EasyTree was kept as a compatibility wrapper. retirement arc complete 🫢
  • XML::Bare β€” very-very fast XML parser. recommend to look. (the author's words, and honestly, valid recommendation πŸ‘€)
  • XML::Hash::LX β€” similar behaviour, same output, but using XML::LibXML. same vibe, different engine πŸ”₯

πŸŽ€ AUTHOR πŸŽ€

Mons Anderson, <mons at cpan.org> β€” king behavior, we stan πŸ‘‘


πŸ¦‹ BUGS πŸ¦‹

None known. (we love a flawless run, no cap ✨)


Copyright 2009 Mons Anderson

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


and that's the tea bestie πŸ“ this page came to you courtesy of perl v5.42.2, dated 2026-02-15, in the XML::Pa...e::ETree(3) section of the docs β€” go forth and parse, you gorgeous genius πŸ’…βœ¨

πŸ“¦ where this page comes from