The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

XML::Tag in short

Teaser examples

XML::Tag takes carre about XML and perl namespaces as well as empty tags. Those examples don't.

Use an existing tagset

Create your own

First,

    package XML::Tag::Sympa;
    use Exporter 'import';
    use XML::Tag;

    BEGIN {
        our @EXPORT = qw< 
        description email env gecos host language list
        listname moderator name owner owner_include port
        pwd query shared_edit shared_read source
        sql status subject topic type user >;

        ns '' => @EXPORT;
    };

    1;

now every keywords of @EXPORT are builders (see the documentation below), you can use them as follow:

    use XML::Tag::Sympa;
    print '<?xml version="1.0">'
    , description {
        email  { 'dave.null@example.com' },
        gecos  { 'Dave Null' },
        status { 'MIA' }, 
        description { +{ lang => "en" },
            "Dave Null is not a number"
        }
    };

The output is

        <?xml version="1.0"><description><email>dave.null@example.com</email><gecos>Dave Null</gecos><status>MIA</status><description lang="en">Dave Null is not a number</description></description>

now extra-space, or indent and this is a feature (please see the FAQ).

I really encourage you to send me your You can also

XML::Tag, a simple XML builder

an XML Builder is a function that generate a rendered html tag.

    use XML::Tag::html5;
    print br;

    use XML::Tag::html5;
    print br;

, optionnally taking a block as argument,

that render a an xml tag in memory. When possible, the function is named on the tag to generate. (See grails taglib for example).

Builders are a set of helpers using

to generate the tag content. I see 3 major gains using this strategy over templating systems:

  • this is

    keep the power of perl in your hands (don't abuse it and respect at least an MVC separation)

  • don't be WYSIWYG. When i write code, i need indentations and line feeds to make things readable. All those extra stuff must disapear in the final result because they are useless and anoying when you manage to control spaces with CSS.

  • stay confident about the quality of generated code: as long as they compiles, the helpers render bug free xml (WARNING: the quality of all PCDATA, attribute values and schemas is *your* job)

see how builders works or see it in action:

To render this text on STDIN.

    <!doctype html><html><head><title lang="fr">my personal homepage</title></head></html> 

you can use directly the tag() function from XML::Tag

    use XML::Tag;
    use Modern::Perl;

    print '<!doctype html>'
    , tag html => sub {
        tag head => sub {
            tag title => sub { +{lang => 'fr'}, "my personal homepage" }
        }
    } 

you can use the ns() function from XML::Tag to generate the helpers

    use XML::Tag;
    use Modern::Perl;

    BEGIN {
        ns '' # use the default namespace
        , qw< html head title > 
    }

    print '<!doctype html>', html {
        head {
            title { +{lang => 'fr'}, "my personal homepage" }
        }
    }

you can even use a ready to use set of helpers

    use XML::Tag::html5;
    print '<!doctype html>', html {
        head {
            title { +{lang => 'fr'}, "my personal homepage" }
        }
    }

XML::Tag functions

tag

ns

tag $name, $content, $attrs

the parameters of tag are

  • $name: the name of the tag

  • $content:

    a sub returning th

        * content sub
        * a hashref with the list of default attributes for the tag 
  • $name ???

    perl -MXML::Tag -E '
        print "($_)" for tag title => sub { "content" },  +{qw(class test)};
    '

    (<)(title)( )(class)(=)("test")(>)(content)(</)(title)(>)


    tag title => sub { "content" },  +{qw(class test)}
    tag title => sub { +{qw(class test)}, "content" }

    use XML::Tag;
    print for tag title => sub { "content" },  +{qw(class test)};


    use XML::Tag;
    print for tag title => sub { "content" },  +{qw(class test)};

    use XML::Tag;
    tag title => sub { "content" },  +{qw(class test)}
    tag title => sub { +{qw(class test)}, "content" }

the content sub returns a list, the first elements of the lists are

    use Modern::Perl;
    use XML::Tag;

    sub foo (&) { tag foo => @_, {qw< isa foo >} }

    print foo{
        + {qw< class bar id bang >}
        , {qw< style text-align:center >}
        , "this is "
        , "the content"
    };

how to build tag list

    extract_elements () {
        xmlstarlet sel -T -t -m '//xs:element/@name' -v . -n "$@"
    }

    schema=http://dublincore.org/schemas/xmls/simpledc20021212.xsd
    curl -ls "$schema" | extract_elements

FAQ

how render indented xml?

there is no way to indent the things as i really

  • wanted to keep this module as simple as possible.

  • strongly believe there is no other good way to render xml (you need indentation to debug? use a indentation tool or any appropriate xml renderer like a web browser).