Jabber::NodeFactory - Simple XML Node Factory for Jabber
my $nf = new Jabber::NodeFactory(fromstr => 1); print $nf->newNode('presence')->toStr; -> <presence/> my $tag1 = $nf->newNode('iq'); $tag1->attr('type', 'get'); my $query = $tag1->insertTag('query', 'jabber:iq:auth'); $query->insertTag('username')->data('qmacro'); print $tag1->toStr; -> <iq type='get'><query xmlns='jabber:iq:auth'> <username>qmacro</username></query></iq> my $tag2 = $nf->newNodeFromStr("<message><body>hi</body></message>"); $tag2->attr('to','firstname.lastname@example.org'); my $msg = $tag2->getTag('body')->data; print $tag2->toStr, "\n"; print $msg; -> <message email@example.com'><body>hi</body></message> -> hi
Jabber::NodeFactory is a library for creating and manipulating XML nodes. It was created to offer similar functions to the xmlnode library in the Jabber server implementation.
It provides enough functions to create and manipulate XML fragments (nodes) in the Jabber XML stream world. The functions are low level, RISC-style :-)
There are two packages - Jabber::NodeFactory and Jabber::NodeFactory::Node. The former is a wrapper which offers two node construction methods; the latter is the package that represents the actual node objects that are created and manipulated.
Use Jabber::NodeFactory to contruct new nodes (which will be Jabber::NodeFactory::Node objects) and Jabber::NodeFactory::Node to manipulate those nodes.
The Connection package will present stream fragments received in the form of Jabber::NodeFactory::Node objects; use Jabber::NodeFactory::Node to parse and manipulate these fragments.
The Jabber::NodeFactory constructor. Call this to create a new Jabber::NodeFactory, with which you can build nodes.
You can create nodes in one of two ways - building them up starting from the tagname (
newNode()), or creating them from a string (
newNodeFromStr()). If you want to be able to do the latter, you need to specify the flag
fromstr => 1
my $nf = new Jabber::NodeFactory(fromstr => 1)
Creating nodes from strings requires the strings to be parsed; an XML parser is only created as part of the Jabber::NodeFactory object being constructed if you set this flag. If you don't set the flag and subsequently try to call
newNodeFromStr(), you'll get an error.
Call this to create a new node. This will return a new Jabber::NodeFactory::Node object. There is one mandatory argument to this call - the name of the tag for the node being created.
my $node = $nf->newNode('tag');
will create a node that looks like this:
If you want to create a node like this, by specifying a tag name, you can also use the
new method in Jabber::NodeFactory::Node to achieve the same thing; the
newNode method has been made available here just to have some consistency with
newNode, this also returns a new Jabber::NodeFactory::Node object. The single argument to be passed is a string. The NodeFactory will use an XML parser to parse this string and create a node or hierarchy of nodes.
my $node = $nf->newNodeFromStr(qq[<test><child attr1='a'/></test>]);
will create a node object that represents the <test> node having a child node as shown.
Construct a new node. Returns a Jabber::NodeFactory::Node object. You must specify a tag name for the node.
my $tag1 = new Jabber::NodeFactory::Node('tag1');
$tag1 represents a node that looks like this:
Returns the name (the tag name) of the node, in the form of a string.
Returns the node's parent. This will be a node object or undef (if it doesn't have a parent).
Sets or gets a node attribute. Pass one argument - an attribute name - to get the value, or two arguments - the name and a value - to set the value. In both cases the value is returned.
$tag1->attr('colour' => 'red'); print $tag1->attr('colour');
Sets or gets a node's data. Pass no arguments to get the data, or one argument - the data - to set the data. In both cases the data is returned.
results in $tag1 representing
<tag1 colour='red'>hello world</tag1>
The common character entities will be encoded/decoded on the fly. These are & (&), " ("), ' ('), < (<) and > (>). This means that if you call data() with the string "this & that", what actually will get stored is "this & that". If you receive a string containing "--> this way", calling data() to retrieve it will give you "--> this way".
See the rawdata() function for a contrast.
Similar to data(), this function allows you to get and set the data for a node. Unlike data(), there is no encoding or decoding of character entities. It's up to you to make sure you don't break the XML stream by sending a stray "<" or something.
This will insert a tag - with the name given in the first (mandatory) argument - into the node object on which the method call is made.
A namespace can be specified in an optional second argument.
my $tag2 = new Jabber::NodeFactory::Node('tag2'); $tag2->insertTag('a'); $tag2->insertTag('b', 'fish:face'); $tag2->insertTag('c')->data('hello');
results in $tag2 looking like this:
Returns a string representation of the node (and all its children).
my $x = new Jabber::NodeFactory::Node('tag'); my $y = $x->insertTag('anothertag'); $y->attr('number',3); print $x->toStr, "\n"; print $y->toStr, "\n";
<tag><anothertag number='3'/></tag> <anothertag number='3'/>
Retrieves a child tag and returns it as a node. Specify the name of the tag to retrieve, and an optional namespace attribute (that must be explicitly specified as an xmlns attribute in the child tag you want) to distinguish it from other tags of the same name.
If you don't know the tagname but know what namespace you want (common in Jabber), then specify an empty string for the tagname.
Will return the <x> tag(s) that have xmlns='jabber:x:event'. If you only want the first one, make the call in scalar context:
my $event = $node->getTag('x','jabber:x:event');
otherwise make it in array context:
my @xtags = $node->getTag('x');
to get multiple tags (node objects).
my $query = $node->getTag('', 'jabber:iq:version');
This gets a 'query' node that's qualified by the iq:version namespace.
Use this method to remove a child tag. Use getTag to identify the tag to remove.
my $tag = $nf->newNodeFromStr(qq[<a><b fruit='banana'>yellow</b></a>]); $tag->getTag('b')->hide; print $tag->toStr;
This returns a list (array) of the direct child tags of the tag on which the method is called.
my $node = $nf->newNodeFromStr(qq[<a><a1/><a2/><a3><a31/></a3></a>]); print $_->name, "\n" foreach $
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.