Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re^2: rough start of an axml compiler

by Logicus
on Aug 02, 2011 at 12:40 UTC ( #918040=note: print w/ replies, xml ) Need Help??


in reply to Re: rough start of an axml compiler
in thread rough start of an axml compiler

Well Boldra, you've thrown a proper little spanner into my works... I'm not complaining because I really like your example!

I was going to run a small number of regex conversions on an aXML string and turn it into classic XML to feed XML::Simple for turning into a perl structure, but I can't do that now if I want to use the method above. .o0(~Hrm~)

One quick question though, under this schema would every tag have to have a definition? As in what would happen to tags which are just markup around and within tags which have defined roles?

Also there is another thought that I don't know exactly how to describe I guess you could call it orphan data, for example:

listing actions/default/body.aXML --------------------------------- <html> <head><title>acme products</title></head> <body> some orphan text that needs to be in the output <use>actions/<qd>action</qd>/main.aXML</use> some more orphan text </body> </html>

I'm guessing that the above would be mapped to your moose solution thusly:

package actions::default::body; my @nodes = ( bless ( { 'tag' => 'html', 'data' => [ bless ( { 'tag' => 'head', 'data' => bless ( { 'tag' => 'title', 'data' => 'acme products' }, 'Node' ), bless ( { 'tag' => 'body', 'data' => [ bless ( { 'tag' => 'orphan', 'data' => 'some orphan text that needs t +o be in the output' }, 'Node' ), bless ( { 'tag' => 'use' 'data' => [ bless ( { 'tag' => 'orphan', 'data' => 'action/'}, 'Node +' ), bless ( { 'tag' => 'qd' 'data' => 'action' }, 'Node +' ), bless ( { 'tag' => 'orphan', 'data' => '/main.aXML' }, ' +Node' ) ] }, 'Node' ) bless ( { 'tag' => 'orphan', 'data' => 'some more orphan text' ), 'Node' ) ] }, 'Node' ) ] }, 'Node' ) ); sub getNodes { return @nodes; } 1;


Comment on Re^2: rough start of an axml compiler
Select or Download Code
Replies are listed 'Best First'.
Re^3: rough start of an axml compiler
by Boldra (Deacon) on Aug 02, 2011 at 13:06 UTC
    Have you considered leaving the untagged content as plain text?
    my @nodes = ( bless ( { 'tag' => 'html', 'data' => [ bless ( { 'tag' => 'head', 'data' => bless ( { 'tag' => 'title', 'data' => 'acme products' }, 'Node' ), bless ( { 'tag' => 'body', 'data' => [ 'some orphan text that needs to be in the + output', bless ( { 'tag' => 'use' 'data' => [ bless ( { 'tag' => 'orphan', 'data' => 'action/'}, 'Node +' ), bless ( { 'tag' => 'qd' 'data' => 'action' }, 'Node +' ), bless ( { 'tag' => 'orphan', 'data' => '/main.aXML' }, ' +Node' ) ] }, 'Node' ) 'some more orphan text', ] }, 'Node' ) ] }, 'Node' ) );
    and it may interest you that with Moose buildargs, you can easily set up the Node constructor to expect a tag and data, e.g. Node->new( qd => 'action' );. The output of Data::Dumper would still contain the bless { }, 'Node' syntax, making it a good place to do debugging and testing.
    my @nodes = ( Node->new( html => [ Node->new( head => Node->new( title => 'acme products' ), ), Node->new( body => [ 'some orphan text that needs to be in the output', Node->new( use => [ 'actions/', Node->new( qd => 'action'), '/main.aXML', ), 'some more orphan text', ], ), ] ), );
    but then why make nodes out of plain html if you have no action planned for them? Checking whether a tag is implemented during parsing is going to save you headaches later.
    my @nodes = ( '<html> <head><title>acme products</title></head> <body> some orphan text that needs to be in the output', Node->new( use => [ 'actions/', Node->new( qd => 'action' ), ' +/main.aXML' ] ), 'some more orphan text </body> </html>', )
    with which print @nodes would just do the right thing.

      That makes life a lot easier!

      The only caveat I can think of is the refas plugin ie :

      (refas tag="user")/path/to/user.xml(/refas) <p>Welcome back <user>username</user>, you were last here on : [time f +ormat="HH:MM:SS, DD/MM/YYY"]<user>lastvisit</user>[/time].</p>

      Where <user> is not a known tag until refas creates a definition for it which maps the user tag data to the nodes in the user.xml file, and [time] takes an integer and gives back a formatted date/time string.

      I was planning on expressing the difference between the three tag types by adding an attribute called aXML_class to the tags when converting them to standard XML :

      (SQL mode="mask") <query> SELECT username,email FROM users; </query> <mask> [link action="showuser" username="<d>username</d>" ]<d>username</d>[/link], [link to="mailto:<d>email</d>"]<d>email</d>[/link] <br> </mask> (/SQL) Becomes : <SQL aXML_class="primary" mode="mask"> <query> SELECT username,email FROM users; </query> <mask> <link aXML_class="tertiary" action="showuser" username="<d>username</d>" ><d>username</d></link>, <link aXML_class="tertiary" to="mailto:<d>email</d>" ><d>email</d></link> <br> </mask> </SQL> Also when tags have tags embedded in their attributes like this : <a b="<c>d</c>">data</a> converting the expression to XML like this; <a aXML_class="standard"> <attr>b="<c aXML_class="standard">d</c>"</attr> <contents>data</contents> </a>

      The examples above would map like this :

      <SQL aXML_class="primary" mode="mask"> <query> SELECT username,email FROM users; </query> <mask> <link aXML_class="tertiary" action="showuser" username="<d>usern +ame</d>"><d>username</d></link>, <link aXML_class="tertiary" to="mailto://<d>email</d>"><d>email< +/d></link> <br> </mask> </SQL> becomes : my @nodes = ( Node->new( SQL => { aXML_class => 'primary', attr => { mode => "mask" }, contents => { '<query>SELECT * FRO +M users</query> <mask>', [ Node->new( link + => { aXML_class => 'tertiary', + attr => { action => 'showuser', + username => '<d>username<d>' }, + contents => '<d>username</d>' + } ), + + contents => '<d>username</d>' } ), Node->new( link + => { aXML_class => 'tertiary', + attr => { to => 'mailto://<d>email</d>' }, + contents => '<d>email</d>' + } ), ], '<br></mask>' } } ) ); and <a b="<c>d</c>">data</a> becomes : <a aXML_class="standard"> <attr>b="<c aXML_class="standard">d</c>"</attr> <contents>data</contents> </a> then becomes : my @nodes = ( Node->new( a => { aXML_class => 'standard', attr => { b => Node->new ( c => +{ aXML_class => 'standard', + contents => 'd' + } ) }, contents => 'data' } } ) );

        Just hacked this together, it only knows about standard tags which are named, and doesn't know about tag attributes, but it is working.

        #!/usr/bin/perl use Modern::Perl; my $knownCmds = '(use|conf|qd)'; $_ = qq@ <html lang="<qd>action</qd>"> <head> <title><conf>site_title</conf></title> </head> <body> some orphan text <use>actions/<qd>action</qd>/somefile.aXML</use> <b>orphan</b> <conf>a</conf> </body> </html> @; #tokenise negatable marker s@`@<caret>@gs; #any text before first knownCmd + s@(.*?)<$knownCmds>@'$1',\n\n<$2>@s; #put negatable marker next to knownCmds + s@<$knownCmds>@<$1>`@gs; s@</$knownCmds>@`</$1>@gs; #any text between any two opens + s@<$knownCmds>`([^`]*?)<$knownCmds>`@<$1>`\n'$2',\n\n<$3>`@gs; #any text between any two closes s@`</$knownCmds>([^`]*?)`</$knownCmds>@`</$1>\n'$2',\n\n`</$3>@gs; #any text between a close and an open s@</$knownCmds>([^`]*?)<$knownCmds>@</$1>\n\n'$2',\n\n<$3>@gs; #any text after last known close s@(.*)</$knownCmds>(.*)@$1</$2>\n'$3'@s; #remove remaining negatable markers s@`@@gs; #de-tokenise negatable marker s@<caret>@`@gs; #convert non-nested tags to node calls + s@<$knownCmds>([^<>]*?)</\1>@Node->new ( $1 => '$2' ),@gs; #convert everything else s@<$knownCmds>(.*?)</\1>@Node->new ( \[ $2 \] ),@gs; #get rid of comma before end of array s@,(\s+?)\]@]@gs; say 'my @nodes = ('; say; say ');';
        OUTPUT :
        my @nodes = ( ' <html lang="', Node->new ( qd => 'action' ), '"> <head> <title>', Node->new ( conf => 'site_title' ), '</title> </head> <body> some orphan text ', Node->new ( [ 'actions/', Node->new ( qd => 'action' ), '/somefile.aXML', ] ), ' <b>orphan</b> ', Node->new ( conf => 'a' ), ' </body> </html> ' );

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://918040]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (9)
As of 2015-07-29 07:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (260 votes), past polls