Было решено, данные сохрянать в xml, ибо так легче рюшики прикручивать. Потом к рюшикам захотелось добавить графики.
Инструментарий:
perl – почти никогда с ним не работала
xsl – работала очень давно и нечего не помню
gnuplot – Услышала это слово уже в процессе работы.
Свои изыскания складываю тут. А вдруг прийдется повторить сей трюк, а я опять все забуду :)
*Все что начинается с my_ - это подстава на месте реальных данных.
I .Создаем на Perl файл с данными в формате xml
Для этого есть такая удобная штука как XML::Simple. С помощью ее очень легко построить xml на основе уже имеющихся древовидных данных, представленных в виде хеша.
Сразу подводный камушек: XML:Simple может быть не уставнолен как модуль perl.
Загружала я его от сюда: http://search.cpan.org/~grantm/XML-Simple-2.18/lib/XML/Simple.pm
О том как поставить читала тут: http://www.mclean.net.nz/cpan/
Вся выгрузка данных в xml-файл занимает три строки:
use XML::Simple;
sub writeXML
{
my $outFileName = shift;
my $simple = XML::Simple->new (ForceArray => 1, KeepRoot => 1);
my $data =\%outHash;
$simple->XMLout($data,
KeepRoot => 1,
OutputFile => $outFileName,
XMLDecl => "<?xml version='1.0'?>",
);
}
для отлаживания процесса создания структуры данных удобно использовать
use Data::Dumper;
print Dumper(\%outHash);
Очень хорошо об этом всем написано вот в этой статье: http://www.ibm.com/developerworks/xml/library/x-xmlperl1.html?ca=dgr-lnxw01XML-Simple
II . Натягиваем xsl - получаем html – пока без графика
На просторах инета несметное количество инфы по этому вопросу, вот то что использовала я:
http://www.citforum.ru/internet/xmlxslt/xmlxslt.shtml
http://www.citforum.ru/internet/xpath/index.shtml
Из того что может пригодится в дальнейшем, это небольшой код для вывода всех аттриботов узлов. Так как этому предшествовала таблица с обобщенной информацией про узлы, каждая такая табличка аттриботов у меня снабжена html-ым якорьком.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/">
<! -- тут табличка и другие удобности-->
<xsl:for-each select="some_path">
<h3>
<a target="_blank">
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
Attributes of <xsl:value-of select="@name"/>
</a>
</h3>
<table border="1">
<tr bgcolor="#CCCCCC">
<td align="center"><strong>name</strong> </td>
<td align="center" ><strong>Data</strong></td>
</tr>
<xsl:for-each select="@*">
<tr bgcolor="#F5F5F5">
<td> <b> <xsl:value-of select="name(.)"/></b></td>
<td> <xsl:value-of select="."/> </td>
</tr>
</xsl:for-each>
</table>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
В табличке для вставки ссылок на якорьки использовала:
<a target="_blank">
<xsl:attribute name="href">#<xsl:value-of select="@name"/></xsl:attribute>
<xsl:attribute name="title"><xsl:value-of select="@name"/></xsl:attribute>
<xsl:value-of select="@name"/>
</a>
Для скрещениявания xml + xsl в Unix есть:
xsltproc -o my_out.html plot_data.xsl my_.xml
III . При момощи xsl готовим данные для gnuplot.
Они должны быть в виде текстового файла, столбцы в файле разделены табуляцией, а строки переводами строки. Кроме того, я не использовала, те данные у которых не установлен соотвествующий аттрибут. Сам xsl вышел вот таким:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes"/>
<xsl:template match="/">
<xsl:for-each select="my_path">
<xsl:if test="@my_attr_name">
<xsl:value-of select="position()"/>
<xsl:text> </xsl:text>
<xsl:value-of select="@my_attr_name"/>
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
При скрещивании его с исходным xml получаем обычный текстовый файл, я ему дала имя out.dat.
IV . gnuplot
Тут я сделала первую стратегическую ошибку. Я спутала gnuplot и gplot.
gplot – это перловый скрипт, который на освновании переданых ему параметров формирует коммандный файл для gnuplot. Причем я скаxала его версии не совместимой с версией моего gnuplot, от чего огребла кучку проблем. В конечном итоге я его не использовала.
Про gnuplot можно почитать :
http://gnuplot.sourceforge.net/ - официальная страничка
http://mydebianblog.blogspot.com/2008/02/gnuplot_18.html — хорошая статья и на русском
http://www.gnuplot.info/faq/faq.html — FAQ
http://www.astri.uni.torun.pl/Manuals/gnuplot/node1.html – manual
Работать с ним можно:
набрать gnuplot и вбивать ему все комманды в ручную (мне этот вариант не подходит)
передав коммандный файл на вход.
В коммандном файле как минимev надо указать:
- терминал на который выводим. В моем варианте это png
- файл куда будет «нарисован» результат
- вызвать функцию plot передав ей входные данные. В моем случае это свормированный нами файлик out.dat
При этом : выходной файл должен быть передан только после указания терминала и перед переходом в режим multiplot (set multiplot). Для коммандного файла я создала шаблон с настройками куда потом отдельно дорисываю строки, содержащие описания входных\выходных данных.
Вот он:
set xlabel "X"
set ylabel "Y"
set multiplot
set autoscale
set data style lines
set border 3
set xtics border nomirror
set ytics border nomirror
set origin 0.0,0.0
set title "Results"
set style line 10 lt 1lw 1 pt 5 ps 0.65
Если все удалось, теперь в xsl формуирующий наш html надо добавить стоки для отображения полученного графического файла:
<img src="out.png"></img><br/>
V . окончательный шелловый скрипт
На вход скрипту передается имя дирректории куда будут сложенные: полученные перлом данные, html файл, данные для построения графика, график в виде png.
Сразу хочу оговорится, тут не стоило бы создавть отдельно файл с данными а сразу выход от xslport подавать на вход к gnuplot, с этим я пока не спела разобраться :( разберусь скажу как.
Пока мой итоговоый скрипт выглядит примерно так:
mkdir $1
echo on;
echo "start script"
./my_script.pl -folder $2 -out $1/out.xml
echo "create data for plot"
xsltproc -o $1/out.data plot_data.xsl $1/out.xml
echo "create plot"
echo "set terminal png" > $1/png.gnuplot
echo "set output \"$1/out.png\"" >> $1/png.gnuplot
cat png.gnuplot >> $1/png.gnuplot
echo "plot \"$1/out.data\"" >>$1/png.gnuplot
echo "" >> $1/png.gnuplot
gnuplot $1/png.gnuplot
echo "create html"
xsltproc -o $1/out.html table.xsl $1/out.xml
rm $1/png.gnuplot
VI . И -то-го
Все просто\быстро\удобно — на коленке получилось. Главное коленки правильные подобрать :)
Обожаю всякие такие утилиты, написанные с применением мощных никсовых тулз. Наверное, профессионализм людей определяется их способностью быстро находить методы решения проблем и скорого освоения программ и языков для этого необходимых.
ОтветитьУдалитьЯ с перлом тоже совсем недавно познакомился, когда надо было написать обработчик для Nginx'a, оказалось все не такой уж сложно, как казалось пять лет назад.