#html #perl
Вопрос:
У меня есть скрипт Perl, который устанавливает соединение с БД и отображает выходные данные в формате HTML. Данные, которые он пытается отобразить, имеют встроенные теги ( < > ), поэтому HTML не отображается. Если я открою фактический HTML-файл, который скрипт генерирует с помощью Блокнота, я увижу данные. Однако я не могу отобразить его из-за тегов. Есть идеи, как это можно исправить?
#!/usr/bin/perl
use DBI;
use HTML::Escape 'escape_html';
unlink("D:\Perl32\scripts\UndeliveredRAW.html");
my $host = '${Node.Caption}';
my $user = '${USER}';
my $pwd = '${PASSWORD}';
my $driver = "SQL Server";
$dbhslam = DBI->connect("dbi:ODBC:Driver=$driver;Server=$host;UID=$user;PWD=$pwd") || die "connect failed:";
$sthslam = $dbhslam->prepare("SELECT
DBA_Reports.dbo.undelivered_raw_host_msgs.ID
DBA_Reports.dbo.undelivered_raw_host_msgs.MESSAGE
FROM
DBA_Reports.dbo.undelivered_raw_host_msgs");
$sthslam->execute;
$msg = "Up";
$Count = 0;
$Output = "";
$Temp = "";
$tbl = "<TABLE border=1 bordercolor=orange cellspacing=0 cellpadding=1>";
$tblhd = "<TR><TH>ID</TH><TH>MESSAGE</TH></TR>";
while (my $ref = $sthslam->fetchrow_hashref()) {
$Count ;
$Output .= '<TR><TD align=center rowspan=1 valign=top width=1000 height=1000>'
. $ref->{'ID'}.'</TD>'
. '<TD align=center rowspan=1 valign=top width=1000 height=1000>'
. escape_html($ref->{'MESSAGE'}).'</TD></TR>';
}
$dbhslam->disconnect;
$Output = "$tbl$tblhd$Output</TABLE>";
my $filename1 = 'D:\Perl32\Scripts\UndeliveredRAW.html';
open(my $fh1, '>', $filename1) or die "Could not open file '$filename1' $!";
print $fh1 "$Output";
close $fh1;
if ($Count > 0) {
$msg = $Output;
}
print "nMessage: $msg";
print "nStatistic: $Count";
Желаемый Результат
Комментарии:
1. Похоже, вам нужно что-то вроде HTML::Escape или HTML::Сущности .
2. О, и всегда
use strict; use warnings;
в сценариях perl.3. Это модуль, который необходимо установить? Увидел эту ошибку, когда попытался использовать ее Ошибка PerlScript: Не удается найти HTML/Escape.pm в @INC (@INC содержит: D:/Perl32/site/lib D:/Perl32/lib .)
4. Вот что я добавил. используйте HTML::Escape qw/escape_html/; escape_html(«<,>»)
5. Образец сгенерированного HTML , добавленный к вашему вопросу, может быть полезен. Я заметил несколько несоответствий: 1. переменные
$host,$user,$pass,$driver
содержат значения в одинарных кавычках, интерполяция не выполняется, 2. в цикле$Count
, но никогда не используется, 3.$Output = "$Output$Temp";
лучше писать$Output .= $Temp;
, Обратите внимание: есть лучшие способы формирования вывода HTML в переменной, что улучшает читаемость/упрощает обслуживание кода.
Ответ №1:
Следующий фрагмент кода демонстрирует слегка измененную версию опубликованного кода.
Пожалуйста, ознакомьтесь с разделом цикла для escape_html(...)
использования с полученными данными базы данных.
#!/usr/bin/env perl
#
# vim: ai ts=4 sw=4
use strict;
use warnings;
use feature 'say';
use DBI;
use HTML::Escape qw/escape_html/;
my $filename = 'D:Perl32scriptsUndeliveredRAW.html';
unlink($filename) if -e $filename;
my $host = ${Node.Caption};
my $user = ${USER};
my $pwd = ${PASSWORD};
my $driver = 'SQL Server';
my $dbh = DBI->connect("dbi:ODBC:Driver=$driver;Server=$host;UID=$user;PWD=$pwd")
or die 'DB connect failed:';
my $query = '
SELECT
DBA_Reports.dbo.undelivered_raw_host_msgs.MESSAGE
FROM
DBA_Reports.dbo.undelivered_raw_host_msgs
';
my $rv = $dbh->do($query) or die $dbh->errstr;
my $msg = 'Up';
my $Count = 0;
my $tbl = '
<TABLE border=1 bordercolor=orange cellspacing=0 cellpadding=1>
<TR><TH>MESSAGE</TH></TR>
';
while (my $ref = $sth->fetchrow_hashref()) {
$Count ;
$tbl .= "nt<TR><TD align=center rowspan=1 valign=top width=5000 height=5000>"
. escape_html($ref->{'MESSAGE'})
. '</TD></TR>';
}
$tbl .= '
</TABLE>
';
my $html =
'<!DOCTYPE html>
<html>
<head>
<title>Undelivered RAW</title>
</head>
<body>
<h1>DB table data</h1>
' . $tbl . '
</body>
</html>
';
open my $fh, '>', $filename
or die "Could not open file '$filename1' $!";
print $fh $html;
close $fh;
if ($Count > 0) {
say 'Message: ' . $msg;
say 'Statistic: ' . $Count";
}
Примечание. чтобы избежать загрязнения кода атрибутами стиля HTML, найдите время для изучения CSS, созданный вами HTML не содержит обязательных разделов DOCTYPE, html, заголовок, заголовок, текст
Ссылка:
Ответ №2:
HTML имеет хорошо понятный механизм включения символов, которые обычно интерпретируются как специальные символы. Например, если вы хотите включить a <
в свой HTML, это обычно будет рассматриваться как начало нового HTML-элемента в вашем документе.
Решение состоит в том, чтобы заменить эти проблемные символы сущностями HTML, которые представляют эти символы. Например, <
следует заменить на amp;<
. Обратите внимание, что это означает, что амперсанд ( amp;
) необходимо добавить в набор символов, которые следует заменить (в данном случае amp;amp;
), если вы хотите включить его в свой HTML.
Perl имеет долгую историю использования в Интернете, поэтому неудивительно, что для выполнения этой замены доступно множество инструментов. HTML::Escape, вероятно, самый известный. Он предоставляет единственную функцию ( escape_html()
), которая принимает текстовую строку и возвращает ту же строку со всеми проблемными символами, замененными соответствующими сущностями.
use HTML::Escape 'escape_html';
my $html = '<some text> amp; <some other text>'
my $escaped_html = escape_html($html);
После запуска этого кода $escaped_html
теперь содержит «$<некоторый текст$> $amp; $<некоторый другой текст$>». И если вы отправите этот текст в браузер, вы получите правильный вывод.
Поэтому самое простое решение-загрузить HTML::Escape в верхней части вашей программы, а затем вызывать escape_html()
всякий раз, когда вы добавляете потенциально проблемные строки в вывод. Это означает, что ваш while
цикл будет выглядеть примерно так:
while (my $ref = $sthslam->fetchrow_hashref()) {
$Count ;
$Output .= '<TR><TD align=center rowspan=1 valign=top width=5000 height=5000>'
. escape_html($ref->{'MESSAGE'})
. '</TD></TR>';
}
Обратите внимание, что я удалил $Temp
переменную (которая, казалось, не делала ничего полезного) и переключился на использование .=
для создания вашей выходной строки. =.
является оператором «объединение назначений» — он добавляет новую строку справа от себя в конец всего, что в настоящее время существует в переменной слева.
Похоже, вы изучаете Perl на работе (что здорово), но очень жаль, что вы изучаете его в среде, которая, похоже, использует методы, которые устарели примерно на двадцать лет. Ваш вопрос-хороший пример того, почему попытка создать необработанные HTML-строки внутри вашего кода Perl-плохая идея. Гораздо лучше использовать какой-либо механизм создания шаблонов (стандартом defacto в мире Perl, по-видимому, является набор инструментов шаблонов).
Я также рекомендую взглянуть на каскадные таблицы стилей как на более современный подход к стилизации вывода HTML.
Комментарии:
1. Большое тебе спасибо, Дэйв, за твое подробное объяснение. У меня был последний вопрос. Мне нужно добавить еще один идентификатор столбца в вывод. Этот столбец не нуждается в какой-либо функции escape. Я добавляю идентификатор в цикл while, однако возникли проблемы. Можете ли вы сообщить мне, чего мне не хватает?
2. @SQLNovice: Не могли бы вы сообщить мне, чего мне не хватает? — Это невозможно, не зная гораздо больше об этой проблеме. Например, какие у вас проблемы? Честно говоря, это звучит как новая проблема, поэтому я рекомендую задать ее как новый вопрос.
3. Мне удалось найти проблему, и я обновил код. Большое вам спасибо за вашу помощь.