examples: Getting the outline of an XHTML page v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Tue, 29 Oct 2019 19:00:52 +0100
branchv_0
changeset 280 eccf2de78284
parent 279 de1b49ba06f1
child 281 0b6b1781a0a5
examples: Getting the outline of an XHTML page
relpipe-data/examples-in-xmltable-xhtml-outline.xml
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/relpipe-data/examples-in-xmltable-xhtml-outline.xml	Tue Oct 29 19:00:52 2019 +0100
@@ -0,0 +1,176 @@
+<stránka
+	xmlns="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/strana"
+	xmlns:m="https://trac.frantovo.cz/xml-web-generator/wiki/xmlns/makro">
+	
+	<nadpis>Getting the outline of an XHTML page</nadpis>
+	<perex>collect list of headlines (or images, links etc.) of a website using XMLTable</perex>
+	<m:pořadí-příkladu>03400</m:pořadí-příkladu>
+
+	<text xmlns="http://www.w3.org/1999/xhtml">
+		
+		<p>
+			Because an XHTML web page is an XML document, it can be processed using XML tools (XSLT, XPath, XQuery etc.).
+			In this example, we will use <code>relpipe-in-xmltable</code> to get list of headlines (outline) and other objects from a web page.
+		</p>
+		
+		<m:pre jazyk="bash"><![CDATA[wget -O - http://blog.frantovo.cz/c/373 \
+	| relpipe-in-xmltable \
+		--namespace 'h' 'http://www.w3.org/1999/xhtml' \
+		--relation 'headlines' \
+			--records '//h:h1|//h:h2' \
+			--attribute 'level'    string 'name()' \
+			--attribute 'headline' string '.' \
+	| relpipe-out-tabular]]></m:pre>
+	
+		<p>
+			This pipeline looks for <code>h1</code> and <code>h2</code> headlines and presents them as a relation.
+			We can fine-tune the XPath expression to get only certain kinds of headlines (this is specific to particular site):
+		</p>
+	
+		<m:pre jazyk="bash"><![CDATA[wget -O - http://blog.frantovo.cz/c/373 \
+	| relpipe-in-xmltable \
+		--namespace 'h' 'http://www.w3.org/1999/xhtml' \
+		--relation 'headlines' \
+			--records '//h:div[@id="obsah"]//h:h1|//h:div[@id="obsah"]//h:h2' \
+			--attribute 'level'    string 'name()' \
+			--attribute 'headline' string '.' \
+	| relpipe-out-tabular]]></m:pre>
+	
+		<p>And get this listing:</p>
+		
+		<m:pre jazyk="text"><![CDATA[headlines:
+ ╭────────────────┬────────────────────────────────────╮
+ │ level (string) │ headline                  (string) │
+ ├────────────────┼────────────────────────────────────┤
+ │ h1             │ Opravujeme myš: výměna spínačů     │
+ │ h2             │ Popis problému                     │
+ │ h2             │ Výdrž 50 milionů kliknutí?         │
+ │ h2             │ Oprava – výměna spínače            │
+ │ h2             │ Myš Razer Orochi                   │
+ │ h2             │ Trackball Logitech TrackMan Marble │
+ │ h2             │ Myší spínače Omron a⎵Panasonic     │
+ │ h2             │ Závěr                              │
+ ╰────────────────┴────────────────────────────────────╯
+Record count: 8]]></m:pre>
+
+		<p>
+			Using slightly modified expressions:
+		</p>
+		
+		<m:pre jazyk="bash"><![CDATA[wget -O - http://blog.frantovo.cz/c/376 \
+	| relpipe-in-xmltable \
+		--namespace 'h' 'http://www.w3.org/1999/xhtml' \
+		--relation 'images' \
+			--records '//h:div[@id="obsah"]//h:img' \
+			--attribute 'image_file' string '@src' \
+			--attribute 'title'      string '@title' \
+	| relpipe-out-tabular]]></m:pre>
+	
+		<p>
+			we will get list of images in different article on the same site:
+		</p>
+	
+	
+		<m:pre jazyk="text"><![CDATA[images:
+ ╭──────────────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────╮
+ │ image_file                      (string) │ title                                                                 (string) │
+ ├──────────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤
+ │ /s/1467/nahled_IMG_2778.JPG              │ Nordic nRF52840, Logitech, bezpečnost bezdrátových myší a klávesnic, MouseJack │
+ │ /s/1472/nahled_IMG_2782.JPG              │ nRF24, hackování bezdrátových klávesnic a myší                                 │
+ │ /s/1465/nahled_IMG_2768.JPG              │ Nordic nRF52840, Logitech, bezpečnost bezdrátových myší a klávesnic, MouseJack │
+ │ /s/1475/logitacker-prikazy.png           │ LOGITacker – rozhraní a příkazy                                                │
+ │ /s/1476/logitacker-zarizeni-modra-1.png  │ LOGITacker – zařízení – bez klávesnice a myši                                  │
+ │ /s/1477/logitacker-zarizeni-modra-2.png  │ LOGITacker – zařízení – rozpoznána klávesnice a myš                            │
+ │ /s/1478/logitacker-zarizeni-zelena-1.png │ LOGITacker – zařízení – dešifrovaná klávesnice a myš                           │
+ │ /s/1463/nahled_IMG_2762.JPG              │ Nordic nRF52840, Logitech, bezpečnost bezdrátových myší a klávesnic, MouseJack │
+ ╰──────────────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────╯
+Record count: 8]]></m:pre>
+
+		<p>
+			There might be multiple <code>--relation</code> sections and we can get multiple relations from a single XML stream:
+		</p>
+		
+		<m:pre jazyk="bash"><![CDATA[wget -O - http://blog.frantovo.cz/c/373 \
+	| relpipe-in-xmltable \
+		--namespace 'h' 'http://www.w3.org/1999/xhtml' \
+		--relation 'headlines' \
+			--records '//h:div[@id="obsah"]//h:h1|//h:div[@id="obsah"]//h:h2' \
+			--attribute 'level'    string 'name()' \
+			--attribute 'headline' string '.' \
+		--relation 'images' \
+			--records '//h:div[@id="obsah"]//h:img' \
+			--attribute 'image_file' string '@src' \
+			--attribute 'title'      string '@title' \
+	| relpipe-out-tabular]]></m:pre>
+	
+		<p>
+			So we can collect various types of objects in a single run.
+			Such data can be stored/catalogized for later use.
+			Or we can e.g. run a shell command for each of them – like if we have a website with some interesting content,
+			we will find the XPath pattern of such content and use it to download desired files: 
+		</p>
+		
+		<m:pre jazyk="bash"><![CDATA[# our favorite function used also in other examples;
+# reads values separated by a \0 byte into a variable;
+# this is a safer way than a space or newline separated data:
+read_nullbyte() { for v in "$@"; do export "$v"; read -r -d '' "$v"; done }
+
+wget -O - http://blog.frantovo.cz/ \
+	| relpipe-in-xmltable \
+		--namespace 'h' 'http://www.w3.org/1999/xhtml' \
+		--relation 'images' \
+			--records '//h:div[@id="plakáty"]//h:img' \
+			--attribute 'image_file' string '@src' \
+	| relpipe-out-nullbyte \
+	| while read_nullbyte img; do wget "https://blog.frantovo.cz$img"; done]]></m:pre>
+	
+		<p>
+			XPath is a very powerful language and allows us to work with the context of the nodes (<a href="https://www.w3.org/TR/xpath-10/#axes">XPath axes</a>)
+			or call various functions – so we can easily pick exactly what we want and download just it, or process it in a different way (compute some statistics, catalogize etc.).
+		</p>
+		
+		<p>
+			n.b. many web pages are poorly written and contain invalid formatting.
+			But fortunatelly there is the <code>tidy</code> tool which can usually clean up such garbage:
+		</p>
+		
+		<m:pre jazyk="bash"><![CDATA[wget -O - https://www.abclinuxu.cz/blog \
+	| tidy -asxhtml -numeric \
+	| relpipe-in-xmltable \
+		--namespace 'h' 'http://www.w3.org/1999/xhtml' \
+		--relation 'headlines' \
+			--records '//h:h1|//h:h2' \
+			--attribute 'level' string 'name()' \
+			--attribute 'title' string 'normalize-space(.)' \
+	| relpipe-tr-awk --relation '.*' --where 'NR <= 10'
+	| relpipe-out-tabular]]></m:pre>
+	
+		<p>
+			so we can fix their mistakes and process even such web sites:
+		</p>
+		
+		<m:pre jazyk="text"><![CDATA[headlines:
+ ╭────────────────┬────────────────────────────────────────────────────╮
+ │ level (string) │ title                                     (string) │
+ ├────────────────┼────────────────────────────────────────────────────┤
+ │ h2             │ KOMIX - Časový posun                               │
+ │ h2             │ Opus Magnum                                        │
+ │ h2             │ Jednoduchá CRUD aplikace (Go a MySQL)              │
+ │ h2             │ Vzdálená správa většího počtu strojů               │
+ │ h2             │ Haluan kadota, vielä paremmin, en koskaan syntynyt │
+ │ h2             │ LibreOffice a viac ako 1024 stĺpcov                │
+ │ h2             │ The Catch CTF 2019                                 │
+ │ h2             │ Zprávička: Nový programovací jazyk Č++             │
+ │ h2             │ Stroj se zastaví                                   │
+ │ h2             │ KOMIX - Užívání                                    │
+ ╰────────────────┴────────────────────────────────────────────────────╯
+Record count: 10]]></m:pre>
+
+		<p>
+			The AWK transformation is used just as an illustration how we can combine various tools together.
+			However, limiting of the records can be done by the <code>--records '(//h:h1|//h:h2)[position() &lt;= 10]'</code> XPath expression in the <code>relpipe-in-xmltable</code> transformation.
+		</p>
+		
+	</text>
+
+</stránka>