Od soboty do úterý probíhá v Hamburku konference 39C3 (Chaos Communication Congress) věnovaná také počítačové bezpečnosti nebo hardwaru. Program (jiná verze) slibuje řadu zajímavých přednášek. Streamy a záznamy budou k dispozici na media.ccc.de.
Byl představen nový Xserver Phoenix, kompletně od nuly vyvíjený v programovacím jazyce Zig. Projekt Phoenix si klade za cíl být moderní alternativou k X.Org serveru.
XLibre Xserver byl 21. prosince vydán ve verzi 25.1.0, 'winter solstice release'. Od založení tohoto forku X.Org serveru se jedná o vůbec první novou minor verzi (inkrementovalo se to druhé číslo v číselném kódu verze).
Wayback byl vydán ve verzi 0.3. Wayback je "tak akorát Waylandu, aby fungoval Xwayland". Jedná se o kompatibilní vrstvu umožňující běh plnohodnotných X11 desktopových prostředí s využitím komponent z Waylandu. Cílem je nakonec nahradit klasický server X.Org, a tím snížit zátěž údržby aplikací X11.
Byla vydána verze 4.0.0 programovacího jazyka Ruby (Wikipedie). S Ruby Box a ZJIT. Ruby lze vyzkoušet na webové stránce TryRuby. U příležitosti 30. narozenin, první veřejná verze Ruby 0.95 byla oznámena 21. prosince 1995, proběhl redesign webových stránek.
Všem čtenářkám a čtenářům AbcLinuxu krásné Vánoce.
Byla vydána nová verze 7.0 linuxové distribuce Parrot OS (Wikipedie). S kódovým názvem Echo. Jedná se o linuxovou distribuci založenou na Debianu a zaměřenou na penetrační testování, digitální forenzní analýzu, reverzní inženýrství, hacking, anonymitu nebo kryptografii. Přehled novinek v příspěvku na blogu.
Vývojáři postmarketOS vydali verzi 25.12 tohoto před osmi lety představeného operačního systému pro chytré telefony vycházejícího z optimalizovaného a nakonfigurovaného Alpine Linuxu s vlastními balíčky. Přehled novinek v příspěvku na blogu. Na výběr jsou 4 uživatelská rozhraní: GNOME Shell on Mobile, KDE Plasma Mobile, Phosh a Sxmo.
Byla vydána nová verze 0.41.0 multimediálního přehrávače mpv (Wikipedie) vycházejícího z přehrávačů MPlayer a mplayer2. Přehled novinek, změn a oprav na GitHubu. Požadován je FFmpeg 6.1 nebo novější a také libplacebo 6.338.2 nebo novější.
Byla vydána nová verze 5.5 (novinky) skriptovacího jazyka Lua (Wikipedie). Po pěti a půl letech od vydání verze 5.4.
tr -td -td -td tr -td -td -td --input --@onclickPřičemž těch řádků je hodně a některé (jako ten první) nenesou žádnou informaci. Ty podstatné řádky mají v poslední buňce input a potřeboval bych znát hodnotu textu v prvních dvou buňkách a parametr onclick elementu input v poslední buňce. Jak na to jít? Napadly mě dvě cesty jak toho dosáhnout: - sed: vymyslet regulární výraz, který z HTML vytáhne zajímavé HTML řádky (každý na jeden plaintext řádek) a pak pomocí prostého s/regexp/\1;\2;\3/ z těchto řádků vytáhnout řetězce a poskládat je. Vůbec ale netuším, vytáhnout ty podstatné HTML řádky - xsltproc --html: Zkusil jsem si vytvořit xsl styl, který tyto informace vytáhne. Nedaří se mi ale vytvořit šablonu tak, abych dostal obsah pouze ze mnou žádaných uzlů, buď se nevypíše nic nebo se vypíše obsah všech textových uzlů. Díky za jakoukoliv pomoc.
Jakmile z toho dostanu jeden HTML řádek na jeden plaintext řádek, tak jsem za vodou
A co třeba:
sed 's#</tr>#</tr>\n#' | sed -n '/<tr>/p' | \ sed 's#<tr><td>\([^<]*\)</td>...<input onclick="\([^"]*\)">...#\1 ..#'
's#</tr>#</tr>\n#' => 's#</tr>#</tr>\n#g'
PS: je to jenom nástřel, možná je to úplně špatně (a nakonec bude to XSLT nejlepším řešením)
--html The input document is an HTML file.
text/html, ve skutečnosti není HTML.
Ještě je tady alternativa někde na pomezí - pokud umíte v AWK, tak bude možná nejrychlejší použít xgawk, což AWK upravený pro zpracování XML (místo řádkových vzorů se používá vzor pro počáteční elementy atp.) - více v dokumentaci.
sedem, jak už jsem psal...
[html]
[head]
[title]titulek[/title]
[script language="javascript"]
skript, ktery obsahuje ruzne [elementy /] a mate tim xsltproc
[/script]
[head]
[body]
[table] [!-- layout --]
[tbody]
[tr]
[td]
[div]
[table]
[script language="javascript"]dalsi skript[/script]
[tbody]
[tr]
[td]nadpis sloupce 1[/td]
[td]nadpis sloupce 2[/td]
[td]nadpis sloupce 3[/td]
[td]nadpis sloupce 4[/td]
[td][/td]
[/tr]
[tr]
[td]text11[/td]
[td]text12[/td]
[td]text13[/td]
[td]text14[/td]
[td][input onclick="akce1"][/td]
[/tr]
[tr]
[td]text21[/td]
[td]text22[/td]
[td]text23[/td]
[td]text24[/td]
[td][input onclick="akce2"][/td]
[/tr][/tbody][/table][/div][/td][/tr][/tbody][/table][/body]přičemž celé <body> je na jednom řádku a potřebuji z toho dostat takovéto .csv:
text11;text12;akce1 text21;text22;akce2
Nejdřív bych naházel každý tag na jeden řádek (teda ukončit řádku za uzavíracím):
sed 's#</[^>]*>#&\n#g'
Tohle by mohlo dát všechny [tr] do jednoho řádku a vytisknout je:
sed -n '/<tr>/{:a;s#</tr>#t k;N;s#\n##;b a;:k;p}'
Možná to nebude fungovat úplně přesně, ale myšlenka (použít N a podmíněný skok t) je snad správná.
Pak by mělo stačit prohnat to grepem a sedem přetransformovat...
user@stroj:~$ w3m tabulky.htm | awk '{...}'
Taky mi z toho není jasné, jestli se v tom inputu objevují nějaké hodnoty generované javascriptem atp. To s ukázkou kódu nasimuluji stěží..
awk '
$0 ~ "[tr]" { ln = 0; }
$0 ~ "[td]" { line[ln++] = $0; }
$0 ~ "[/tr]" { print line[0] line[1] line[2] line[3] line[4]; }
' < file.html | sed 's/.../\1 \2 \3 \4 \5/'
Ten sed už zvládneš určitě sám...
#!/usr/bin/env perl
use strict;
use warnings;
undef $/;
$_ = <>;
my @ctx = m{
<tr>\s* # Úvodní TR
<td>([^<]*)</td>\s* # První buňka
<td>([^<]*)</td>\s* # Druhá buňka
(?:<td>[^<]*</td>\s*)* # Zbývající buňky
<td><input\s*onclick="(.*?)"> # INPUT, od kterého se odpíchneme
(?{print "$1;$2;$3\n"}) # Vypsat výstup
}gsx;
Na zadané ukázce frčí dobře:
zoul@naima:~$ ./tabulky.pl < vstup.html text11;text12;akce1 text21;text22;akce2 zoul@naima:~$
<tr[^>]*>([^<]*)</td>\s* # První buňka?
#!/usr/bin/env perl -w0n
my @ctx = m{
<tr[^>]*>\s*
<td[^>]*>([^<]*)</td>\s*
<td[^>]*>([^<]*)</td>\s*
(?:<td[^>]*>[^<]*</td>\s*)*
<td[^>]*><input\s*onclick="(.*?)">
(?{print "$1;$2;$3\n"})
}gsx;
Byl bych řekl, že místo těžkopádného [^>]* (cokoliv kromě znaku >) bude fungovat i skromné srovnávání (.*?), ale to mi z nějakého důvodu nešlo.
<?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="text"/> <xsl:template match="/html/body/table/tbody/tr/td/div/table/tbody/tr[td[last()]/input]"> <xsl:value-of select="td[1]"/>;<xsl:value-of select="td[2]"/>;<xsl:value-of select="td[last()]/input/@onclick"/> <xsl:text> </xsl:text> </xsl:template> <xsl:template match="*"><xsl:apply-templates select="*" /></xsl:template> </xsl:stylesheet>
creating dictionary for stylesheet reusing dictionary from opory.xsl for stylesheet xsltParseStylesheetProcess : found stylesheet xsltPrecomputeStylesheet: removing ignorable blank node xsltParseTemplateContent: removing text xsltCompilePattern : parsing '/html/body/table/tbody/tr/td/div/div/table/tbody/tr[td[last()]/input]' xsltCompilePattern : parsed /html/body/table/tbody/tr/td/div/div/table/tbody/tr[td[last()]/input], default priority 0.500000 added pattern : '/html/body/table/tbody/tr/td/div/div/table/tbody/tr[td[last()]/input]' priority 0.500000 xsltCompilePattern : parsing '*' xsltCompilePattern : parsed *, default priority -0.500000 added pattern : '*' priority -0.500000 parsed 2 templates Resolving attribute sets references Creating sub-dictionary from stylesheet for transformation Registered 0 modules reusing transformation dict for output Registering global variables Registering global variables from opory.xsl xsltProcessOneNode: no template found for / xsltProcessOneNode: applying template '*' for html xsltApplyTemplates: node: 'html' xsltApplyTemplates: select * xsltApplyTemplates: list of 2 nodes (...) xsltProcessOneNode: applying template '*' for tr xsltApplyTemplates: node: 'tr' xsltApplyTemplates: select * xsltApplyTemplates: list of 6 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 1 nodes xsltProcessOneNode: applying template '*' for input xsltApplyTemplates: node: 'input' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodesa v podobném duchu pokračuje dalších ~ 17k řádků.
/html/body/table/tbody/tr/td/div/tabletak, aby se chytil na tu správnou tabulku. Pokud v tom html jsou nějaká id, je nejlepší se chytit na ně. Jinak je potřeba zvolit správné pořadí elementů. Pokud ty tagy
<input> jinde na stránce nejsou, můžete taky zkusit /html/body//table/tbody/tr[td[last()]/input]
/html/body/table/tbody/tr/td/div/div/table/tbody/tr[td[last()]/input]a výsledek jsem posílal minule.
Pokud v tom html jsou nějaká id, je nejlepší se chytit na ně.Vnější div má id "
p_r_i_n_t". Zkusil jsem vztáhnout xpath výraz od něj:
id('p_r_i_n_t')/div/table/tbody/tr[td[last()]/input]
a výsledek se od předchozího nijak neliší:
Celé XML sem nechci posílat, tak dávám alespoň odkaz na zastřelenou obrazovku DOM inspektoru.
//div[@id='p_r_i_n_t']/div/table/tbody/tr[td[last()]/input]A podívejte se, jak jsou tagy zapsané v tom očištěném (XHTML) souboru, zda jsou malými písmeny, resp. přizpůsobte velikost písmen v XPath. Případně sem pošlete (nebo někam vystavte, přinejhorším pošlete e-mailem) alespoň začátek to XML – aby tam byl alespň jeden řádek s daty. Ta data a texty klidně nahraďte něčím jiným.
<div id='p_r_i_n_t'>
<div align='center'>
<h2>nadpis 2</h2>
<p>lorem ipsum ...</p>
<table border='1'>
<tr>
<th>nadpis 1</th>
<th>nadpis 2</th>
<th>nadpis 3</th>
<th>nadpis 4</th>
<th>nadpis 5</th>
<th>nadpis 6</th>
</tr>
<tr bgcolor="">
<td>text11</td>
<td>text12</td>
<td>text13</td>
<td align='right'>text14</td>
<td align='right'>text15</td>
<td><input type='button' value='Otevřít' onclick=
'js_fce("id")' /></td>
</tr>
<tr bgcolor="#FFCCCC">
<td>text21</td>
<td>text22</td>
<td>text23</td>
<td align='right'>text24</td>
<td align='right'>text25</td>
<td><input type='button' value='Otevřít' onclick=
'js_fce("id")' /></td>
</tr>
(...)
</table>
</div>
</div>Xpath výraz jsem podle toho upravil takto:
//div[@id='p_r_i_n_t']/div/table/tr[td[last()]/input]a xsltproc si stále mele svou:
creating dictionary for stylesheet reusing dictionary from opory.xsl for stylesheet xsltParseStylesheetProcess : found stylesheet xsltPrecomputeStylesheet: removing ignorable blank node xsltParseTemplateContent: removing text xsltCompilePattern : parsing '//div[@id='p_r_i_n_t']/div/table/tr[td[last()]/input]' xsltCompilePattern : parsed //div[@id='p_r_i_n_t']/div/table/tr[td[last()]/input], default priority 0.500000 added pattern : '//div[@id='p_r_i_n_t']/div/table/tr[td[last()]/input]' priority 0.500000 xsltCompilePattern : parsing '*' xsltCompilePattern : parsed *, default priority -0.500000 added pattern : '*' priority -0.500000 parsed 2 templates Resolving attribute sets references Creating sub-dictionary from stylesheet for transformation Registered 0 modules reusing transformation dict for output Registering global variables Registering global variables from opory.xsl xsltProcessOneNode: no template found for / xsltProcessOneNode: applying template '*' for html xsltApplyTemplates: node: 'html' xsltApplyTemplates: select * xsltApplyTemplates: list of 2 nodes (...) xsltProcessOneNode: applying template '*' for div xsltApplyTemplates: node: 'div' xsltApplyTemplates: select * xsltApplyTemplates: list of 1 nodes xsltProcessOneNode: applying template '*' for div xsltApplyTemplates: node: 'div' xsltApplyTemplates: select * xsltApplyTemplates: list of 3 nodes xsltProcessOneNode: applying template '*' for h2 xsltApplyTemplates: node: 'h2' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for p xsltApplyTemplates: node: 'p' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for table xsltApplyTemplates: node: 'table' xsltApplyTemplates: select * xsltApplyTemplates: list of 531 nodes (radek s nadpisy) xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes xsltProcessOneNode: applying template '*' for td xsltApplyTemplates: node: 'td' xsltApplyTemplates: select * xsltApplyTemplates: list of 1 nodes xsltProcessOneNode: applying template '*' for input xsltApplyTemplates: node: 'input' xsltApplyTemplates: select * xsltApplyTemplates: list of 0 nodes
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="text"/>
<xsl:template match="tr[td[last()]/input]"> <xsl:value-of
select="td[1]"/>;<xsl:value-of select="td[2]"/>;<xsl:value-of
select="td[last()]/input/@onclick"/> <xsl:text>
</xsl:text>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="//div[@id='p_r_i_n_t']/div/table"/>
</xsl:template>
</xsl:stylesheet>
Takže s přeskočením nezajímavých textů by to mělo vypadat:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="text"/>
<xsl:template match="tr[td[last()]/input]"><xsl:value-of
select="td[1]"/>;<xsl:value-of select="td[2]"/>;<xsl:value-of
select="td[last()]/input/@onclick"/><xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="//div[@id='p_r_i_n_t']/div/table"/>
</xsl:template>
<xsl:template match="*"><xsl:apply-templates select="*" /></xsl:template>
</xsl:stylesheet>
<div> níže, transformace funguje, ale pokud mu podstrčím celé html, tak se mu nechce. Mimochodem umí XSL vyříznout z onoho <input onclick='jsFunkce("číselné_ID")'/> ono číselné_ID?
<html> jmenný prostor? Ale to by snad xsltproc něco zahlásil…
Pokud je jsFunkce("…") (to okolo) vždy stejné, dalo by se použít funkcí substring a string-length, případně replace. Např.
<xsl:value-of select="replace(td[last()]/input/@onclick,'jsFunkce\("(.*)"\)','$1')"/>
<html xmlns="http://www.w3.org/1999/xhtml">
Pokud jeJe. Takto to vypadá dobře, jestli to bude funkční uvidíme až po vyřešení toho namespace.jsFunkce("…")(to okolo) vždy stejné, dalo by se použít funkcísubstringastring-length, případněreplace.
<?xml version="1.0" encoding="UTF-8" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml" version="1.0"> …
sed -e 's/\ / /g;s/<html[^>]*>/<html>/;s/jsFunkce(\"\([^"]*\)\")/\1/;'Díky všem za čas a pomoc.
Nicméně DOM inspektor pěkně kecá, protože žádný tag tbody v původním ani očištěném html není!No jo, na tenhle oblíbený trik jsem zapomněl. On zobrazuje skutečný aktuální DOM dokumentu, tj. to co vznikne parsováním a „hádáním“ toho, jak ten dokument má správně vypadat.
xsltproc v tom ukecaném výstupu zmínilo.
Tiskni
Sdílej: