On 24/02/2012 00:17, Webley Silvernail wrote:
On 23/02/2012 00:59, Webley Silvernail wrote:

Hey Webley

Approach II is the correct one. The problem is with the way you are
adding your new content, which is presumably as a text string (in which
case HTML::Element is correct to render it as text!).

The correct way is to build an HTML::Element tree with calls like

  my $tree = HTML::TreeBuilder->new_from_content($content);

    my $new = HTML::ELement->new('b');
    $new->push_content('This text in BOLD');

    my $place = $tree->look_down(_tag =>  'div', id =>  'insertion');
    $place->push_content($new);

all depending on what you want to insert and how you locate the place in
the document to insert it. The above will build content like

  <b>This text in BOLD</b>

and insert it under an element marked

  <div id="insertion">

An alternative is to pass your new string to HTML::Treebuilder to build
a new HTML fragment from your string and then insert that into your
document.

Hello Webley. See my comments below.

Thanks for the response. I *think* I'm already inserting my content
in the way you describe, but perhaps I am not. I should have been
less generic in my original message. >

My script connects to a database to retrieve the current day's
updates. It uses these results to update the HTML page either with a
table summarizing the new data or a message indicating that no new
records were added.

I am using HTML::Element->new() to create new
elements and then using either push_content() or unshift_content() to
insert the new content back into my tree object.

Here's my tree object:
my $root = HTML::TreeBuilder->new;       # Is new_from_content different? It 
doesn't seem so from Perldoc, but I could be wrong.

They are very different:

  my $root = HTML::TreeBuilder->new_from_content($content)

is the same as

  my $root = HTML::TreeBuilder->new;
  $root->parse($content);
  $root->eof;

and without parsing some sort of HTML to start with you are working with
an empty HTML tree.

And a fragment within the tree:
my $content = $root->look_down('id', 'fmsbody');

Unless you have parsed some HTML here your look_down will find nothing!

Here's an example of new content being inserted:

     my $div_date = HTML::Element->new('div','class'=>'date');
     $content->unshift_content($div_date);

The table is being constructed from a couple of subroutines. One
creates the header row, the other cycles through the resultset to
create the data rows.

Here's the part where the table is created:

       my $scn7_table = HTML::Element->new('table', 'class'=>'fmtable');
       my @scn7_col_heads = qw(EX FC TYPE DESCRIPTION);
       my $scn7_table_head = create_heading_row(\@scn7_col_heads);
       $scn7_table->push_content($scn7_table_head);

And here's the subroutine to insert the detail row which is where
the  only bad content will wind up:

sub create_detail_row {
my $data = shift;
my @recs = @$data;

       my $row = HTML::Element->new('tr');
       my $cell = HTML::Element->new('td', 'class'=>'fmdata');

       for (my $i=0; $i<= $#recs; $i++) {
           $row->push_content($cell->starttag().$recs[$i].$cell->endtag());
       }
       return $row;
}

Here is your problem. starttag and endtag return *strings*, and you are passing

    "<td class="fmdata">$recs[$i]</td>"

to the push_content method. That is a single text element and you are
losing the <td> element that should contain the text value in $recs[$i].

Write this instead

  sub create_detail_row {

    my $data = shift;

    my $tr = HTML::Element->new('tr');

    foreach my $text (@$data) {
      my $td = HTML::Element->new('td', class => 'fmdata');
      $td->push_content($text);
      $tr->push_content($td);
    }

    return $tr;
  }

It is called like this:

#Create detail rows and insert into table
while (my @recs = $sth7->fetchrow_array) {
            my $row = create_detail_row(\@recs);
            $scn7_table->push_content($row);
       }
       #Insert table into document tree
       $div_date->push_content($scn7_table);

Since the detail rows are where the problem lies, maybe that's the
spot I need to check?  The
$row->push_content($cell->starttag().$recs[$i].$cell->endtag());
part?  I was thinking that by the time I get to the print OUT
$root->as_HTML part, everything should be good to go, but alas that
is not the case.

Indeed. I hope you understand why now?

The problem data is a 2-char code that can be any combination of the
alphanumerics plus a handful of special characters. In my original
message, I used '<B' as an example, but that could also have been
'<3' or '<%' or '<I'.   I guess HTML rendering agents would be more
prone to choking on<B,<I,<A, etc., though.

Once your HTML tree is built, you need to write

  print OUT $root->as_HTML('<>&', '  ');

and all should be well.

Cheers,

Rob

--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to