=head1 NAME
XML::Smart::Tutorial - Tutorial and examples for XML::Smart.
=head1 SYNOPSIS
This document is a tutorial for I<XML::Smart> and shows some examples of usual things.
=head1 Working with contents:
In I<XML::Smart> the key I<CONTENT> is reserved and shouldn't be used directly,
since I<XML::Smart> will deal with the convertion of arguments to node contents,
including multiple node contents autimatically.
=head2 What happens when you set a value:
$xml->{root}{foo} = 'simple value' ;
Here foo will be a normal argument/attribute value, and will generate this XML data:
<root foo="simple value"/>
But if you insert some tag or lines in the values by default I<XML::Smart> will convert it to a node content:
$xml->{root}{foo} = "line0\nlien1\nline2\n" ;
And will generate that XML data:
<root>
<foo>line0
lien1
line2
</foo>
</root>
But what you can do if you want to force some type, let's say, have a node content with a simple value:
$xml->{root}{foo} = 'simple value' ;
$xml->{root}{foo}->set_node(1) ;
And will generate that XML data:
<root>
<foo>simple value</foo>
</root>
=head2 Multiple contents:
When you have interpolated content/data you need to work in a different. Let's say that you load
this XML data:
<root>
content0
<tag1 arg="1"/>
content1
</root>
If you access directly the root key as string you will get all the content parts grouped.
So, this code:
my $xml = new XML::Smart(q`
<root>
content0
<tag1 arg="1"/>
content1
</root>
`,'smart') ;
print "#$xml->{root}#" ;
Will print that:
#
content0
content1
#
B<To access each part of the content independently you should use an array that receive the method I<content()>:>
my @content = $xml->{root}->content ;
print "#$content[0]#\n" ;
And this will print that:
#
content0
#
B<Now to set the multiple content values you should use the method I<content()> with 2 arguments:>
$xml->{root}->content(0,'new content') ;
And now the XML data produced will be:
<root>new content<tag1 arg="1"/>
content1
</root>
If you use the method I<content()> with only one argument it will remove all the multiple contents and will set
the new value in the place of the 1st content.
=head1 Setting the XML Parser.
By defaul I<XML::Smart> will use L<XML::Parser> or L<XML::Smart::Parser> (in this order of preference) to load a XML data.
To force or define by your self the parser you can use the 2nd argument option when creating a I<XML::Smart> object:
my $xml = new XML::Smart( 'some.xml' , 'XML::Parser' ) ;
## and
my $xml = new XML::Smart( 'some.xml' , 'XML::Smart::Parser' ) ;
I<XML::Smart> also has an extra parser, I<XML::Smart::HTMLParser>, that can be used to load HTML as XML, or to load wild XML data:
my $xml = new XML::Smart( 'some.xml' , 'XML::Smart::HTMLParser' ) ;
Aliases for the parser options:
SMART|REGEXP => XML::Smart::Parser
HTML => XML::Smart::HTMLParser
So, you can use as:
my $xml = new XML::Smart( 'some.xml' , 'smart' ) ;
my $xml = new XML::Smart( 'some.xml' , 'html' ) ;
=head1 Customizing the Parser.
You can customize the way that the parser will treat the XML data:
=head2 Forcing nodes/tags and arguments/attributes to lowercase or upercase:
## For lower case:
my $xml = new XML::Smart( 'some.xml' ,
lowtag => 1 ,
lowarg => 1 ,
) ;
## For uper case:
my $xml = new XML::Smart( 'some.xml' ,
upertag => 1 ,
uperarg => 1 ,
) ;
=head2 Loading arguments without values (flags) as a TRUE boolean:
I<** Note, this option will work only when the XML is parsed by XML::Smart::HTMLParser, since only it accept arguments without values!>
my $xml = new XML::Smart(
'<root><foo arg1="" flag></root>' ,
'XML::Smart::HTMLParser' ,
arg_single => 1 ,
) ;
Here's the tree of the example above:
'root' => {
'foo' => {
'flag' => 1,
'arg1' => ''
},
},
=head2 Customizing the parse events:
I<XML::Smart> can redirect the parsing process to personalized functions:
my $xml = XML::Smart->new( 'some.xml' ,
on_start => \&on_start ,
on_char => \&on_char ,
on_end => \&on_end ,
) ;
sub on_start {
my ( $tag , $pointer , $pointer_back ) = @_ ;
$pointer->{$tag}{type_user} = 1 if $tag =~ /(?:name|age)/ ;
}
sub on_char {
my ( $tag , $pointer , $pointer_back , $content) = @_ ;
$$content =~ s/\s+/ /gs ;
}
sub on_end {
my ( $tag , $pointer , $pointer_back ) = @_ ;
$pointer->{$tag}{type_extra} = 1 if $tag =~ /(?:more|tel|address)/ ;
}
=head1 AUTHOR
Graciliano M. P. <gm@virtuasites.com.br>
I will appreciate any type of feedback (include your opinions and/or suggestions). ;-P
Enjoy and thanks for who are enjoying this tool and have sent e-mails! ;-P
=head1 ePod
This document was written in L<ePod> (easy-POD), than converted to POD, and from here you know the way.
=cut