Hi!
I've had some ideas about how to improve TaglibHelper. Currently, I dislike
the way input and output is handled - there is no way to express certain XML
structures, and for some input, information is lost. (see the TaglibHelper
manpage, the person example:
<friends><pid>3</pid><pid>5</pid><pid>13</pid></friends> is converted into
friends => [ 3, 5, 13 ] - the sub doesn't know what name the inner tags had)
Moreover, there is no real distinction beween attributes and content tags,
which is bad, IMHO. So I developed a different TaglibHelper API, and the best
part is: it can coexist with the current TaglibHelper in the same module.
I think I will implement it for my own forthcoming taglibs, as it seems to me
to be a natural way of doing things.
My questions are: Is it really a good idea? Did I miss something? Is it
useful to put it into the existing TaglibHelper? or even replace it somewhen?
Why/When could the old TaglibHelper be better?
Please CC me, since I don't want to join yet another mailing list.
Here is my concept:
CONCEPT
* Configuration via %EXPORT_TAGLIB hash
* keys are tag names
* values are sub refs or array refs (start&end handler)
Example:
%EXPORT_TAGLIB = {
'test' => \&foo,
'pass-through' => [ sub { "if (1) { " }, sub { "}" } ],
};
* subs get one parameter: hashref of xml content (only containing
' attributes' entry if using start & end handler)
* xml content is structured like this:
XML fragment:
<myxmlns:test attr="blah" name="bar">
<foo name="1">foo</foo>
<attr>baz</attr>
<complex>
<age>25</age>
<friend>Horst</friend>
<friend>Helga</friend>
<description>He is a <b>very</b> dumb man without
<not-so-bold>any</not-so-bold>attitude.</description>
</complex>
<attr><b>haha!</b></attr>
</myxmlns:test>
resulting hashref:
{
' attributes' => { 'attr' => 'blah', 'name' => 'bar' },
' order' => [ 'foo', 'attr', 'complex', 'attr' ],
'foo' => {
' attributes' => { 'name' => 1 },
' order' => [ ' CDATA' ],
' CDATA' => 'foo'
},
'attr' => [
'baz',
{
' order' => [ 'b' ],
'b' => { ' order' => [ ' CDATA' ], ' CDATA' =>
'haha!' },
},
],
'complex' => {
' order' => [ 'age', 'friend', 'friend', 'description' ],
'age' => '25',
'friend' => [ 'Horst', 'Helga' ],
'description' => {
' order' => [ ' CDATA', 'b', ' CDATA', 'not-so-bold',
' CDATA' ],
' CDATA' => [ 'He is a ', ' dumb man without ',
'attitude.' ],
'b' => 'very',
'not-so-bold' => 'any',
},
}
* advantage: 100% accurate reconstruction is possible, mixing the two
modes of operation (start&end event vs. whole content at once)
* disadvantage: more handling needed in handler subs, since there is
more than one representation of the same input - can be solved by
providing utility methods, e.g.:
getScalar( ['bla'] ) eq getScalar( 'bla' ) eq 'bla'
eq getScalar( {' CDATA' => 'bla', ' order' => [ ' CDATA' ]} )
or:
attrOrSubtag( {'foo' => 'bar'} ) eq
attrOrSubtag( {' attributes' => { 'foo' => 'bar' }} )
* both modes of operation could coexist dure to the new configuration
variable (perhaps deprecate the old way of doing things?)
* return value is structured likewise, so you can easily pass on parts of
the hashref tree unmodified
EXAMPLE
This effectively leaves the result of a XSP page unmodified:
package Apache::AxKit::Language::XSP::Test;
use Apache::AxKit::Language::XSP::TaglibHelper;
use strict;
sub foo($) {
my $content = shift;
# there is no container element generated for the top level hash!
# because of that, the contained ' attibute' element is ignored
# 'getArray' and 'getHash' would be one of the possible helper
functions
return { getHash($content),
' order' => [ ' CDATA', getArray($$content{' order'}), '
CDATA' ],
' CDATA' => [ 'if (1) { ', getArray($$content{'
CDATA'}),' }' ],
};
}
$NS = 'http://xmlns.creITve.de/test/';
%EXPORT_TAGLIB = {
'test' => \&foo,
'pass-through' => [ sub { "if (1) { " }, sub { "}" } ],
};
--
CU
Joerg
PGP Public Key at http://ich.bin.kein.hoschi.de/~trouble/public_key.asc
PGP Key fingerprint = D34F 57C4 99D8 8F16 E16E 7779 CDDC 41A4 4C48 6F94
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]