|
Guides All Guides and HOWTO's. |
|
Thread Tools | Display Modes |
|
|||
A XHTML makeover of 'vmstat -iz' output by cosmetic surgeons Dr. XML and Dr. XSLT
A XHTML makeover of 'vmstat -iz' output by cosmetic surgeons Dr. XML and Dr. XSLT
1.1 Abstract This guide or tutorial will show how to convert plain text output of the OpenBSD vmstat -iz command to XML, using 'sed', the Unix stream editor. The XML formatted data will be the source for a XSLT transformation into XHTML. The XSLT transformation will be done according to the transformation templates of the presented XSL stylesheet. The conversion of the XML file into XHTML will be done by an XSLT processor, for example by the built-in XSLT engine of Firefox. From the standalone XSLT processors, the usage of Sablotron and Xalan will be demonstrated. 1.2 The plain text output from 'vmstat -iz' According to the OpenBSD man page for 'vmstat' this program "reports certain kernel statistics kept about process, virtual memory, disk, trap, and CPU activity" The '-i' option "reports on the number of interrupts (traps) taken by each device since system startup", while the '-z' option also "lists devices which have not yet generated an interrupt". Code:
$ ssh j65nko@parmenides 'vmstat -iz' >vmstat.txt $ cat vmstat.txt interrupt total rate irq14/pciide0 179284 0 irq11/uhci0 0 0 irq10/xl0 5115342 2 irq12/fxp0 4880752 2 irq1/pckbc0 4981 0 irq7/lpt0 0 0 irq4/pccom0 0 0 irq3/pccom1 0 0 irq6/fdc0 0 0 irq5/wss1 0 0 irq9/mpu0 0 0 irq0/clock 243870818 99 irq8/rtc 312161132 127 Total 566212309 232 The XML version looks like this: Code:
<?xml version='1.0' encoding='UTF-8' ?> <?xml-stylesheet href='vmstat-i.xsl' type='text/xsl' ?> <!-- generated by 'sed(1)' --> <vmstat-i> <irq nr='14' dev='pciide0' total="179284" rate="0" /> <irq nr='11' dev='uhci0' total="0" rate="0" /> <irq nr='10' dev='xl0' total="5115342" rate="2" /> <irq nr='12' dev='fxp0' total="4880752" rate="2" /> <irq nr='1' dev='pckbc0' total="4981" rate="0" /> <irq nr='7' dev='lpt0' total="0" rate="0" /> <irq nr='4' dev='pccom0' total="0" rate="0" /> <irq nr='3' dev='pccom1' total="0" rate="0" /> <irq nr='6' dev='fdc0' total="0" rate="0" /> <irq nr='5' dev='wss1' total="0" rate="0" /> <irq nr='9' dev='mpu0' total="0" rate="0" /> <irq nr='0' dev='clock' total="243870818" rate="99" /> <irq nr='8' dev='rtc' total="312161132" rate="127" /> <summary grandtotal='566212309' grate='232' /> </vmstat-i> Another possible valid XML format, although more bulky, would be: Code:
<vmstat-i> <irq> <nr>14</nr> <dev>pciide0</dev> <total>179284</total> <rate>0</rate> </irq> <irq> ...... </irq> </vmstat-i> 1.3 The 'vmstat2xml.sed' command file for 'sed(1)' The conversion to XML is simple enough to be done by 'sed'. Code:
1 # -- sed command file to XMLize 'vmstat -iz' output 2 3 1c\ 4 <?xml version='1.0' encoding='UTF-8' ?>\ 5 <?xml-stylesheet href='vmstat-i.xsl' type='text/xsl' ?>\ 6 \ 7 <!-- generated by 'sed(1)' -->\ 8 \ 9 <vmstat-i> 10 11 s~irq\([0-9][0-9]*\)/\([^ ][^ ]*\) *\([0-9][0-9]*\) *\([0-9][0-9]*\)~ <irq nr='\1' dev='\2' total="\3" rate="\4" />~ 12 13 ${ 14 s~^[Tt]otal *\([0-9][0-9]*\) *\([0-9][0-9]*\)~ <summary grandtotal='\1' grate='\2' />~p 15 a\ 16 </vmstat-i> 17 }
According to the man page, The format of a sed command is as follows: Code:
[address[,address]]function[arguments] Code:
[2addr]c\ text Delete the pattern space. With 0 or 1 address or at the end of a 2-address range, text is written to the standard output. The argument text consists of one or more lines. To embed a newline in the text, precede it with a backslash. Other backslashes in text are deleted and the following character taken literally Code:
3 1c\ 4 <?xml version='1.0' encoding='UTF-8' ?>\ 5 <?xml-stylesheet href='vmstat-i.xsl' type='text/xsl' ?>\ 6 \ 7 <!-- generated by 'sed(1)' -->\ 8 \ 9 <vmstat-i> If we copy lines 3-9 to the file 'cmd-1' we get the following result: Code:
$ sed -ne '3,9p' vmstat2xml.sed >cmd-1 $ sed -f cmd-1 vmstat.txt <?xml version='1.0' encoding='UTF-8' ?> <?xml-stylesheet href='vmstat-i.xsl' type='text/xsl' ?> <!-- generated by 'sed(1)' --> <vmstat-i> irq14/pciide0 179284 0 irq11/uhci0 0 0 irq10/xl0 5115342 2 [output snipped] irq0/clock 243870818 99 irq8/rtc 312161132 127 Total 566212309 232 The second command has to change Code:
irq14/pciide0 179284 0 Code:
<irq nr='14' dev='pciide0' total="179284" rate="0" /> 'sed' uses the Basic Regular Expressions (BRE) as described in the re_format(7) man page. sed(1) describes two 'sed' specific additions to the BRE. A short overview of the major regular expression used:
The general format of search and replace: s/search_pattern/replacement/ The '/' is used a a delimiter to indicate the start and end of the search pattern and replacement text. In our case we have to match the '/' of 'irq14/pciide0'. To match this forward slash we would have to use a backslash to escape the forward slash: '\/'. A comfortable way to avoid this 'leaning toothpick' syndrome. is to use custom delimiters. I used a tilde '~', so the format becomes: s~search_pattern~replacement~ Explanation of the regular expression: Code:
s~irq\([0-9][0-9]*\)/\([^ ][^ ]*\) *\([0-9][0-9]*\) *\([0-9][0-9]*\)~ Sample text : 'irq14/pciide0 179284 0' s : substitute function ~ : custom delimiter indicating start of the search pattern irq : the string 'irq' /* The irq number for 'irq=' attribute */ \( : start saving in container '\1' [0-9] : a single digit [0-9]* : optionally followed by more digits \) : stop saving in container '\1' / : a '/' which indicates start of te device name /* the device name for 'dev=' attribute */ \( : start saving in next container '\2' [^ ] : a non-space or non-blank [^ ]* : optionally followed by more non-blanks \) : stop saving in container '\2' * : a space, optionally followed by more spaces /* total number of interrupts for 'total=' attribute */ \( : start saving in next container '\3' [0-9] : a single digit [0-9]* : optionally followed by more digits \) : stop saving in container '\3' * : a space, optionally followed by more spaces /* the interrupt rate for 'rate=' attribute */ \( : start saving in next container '\4' [0-9] : a single digit [0-9]* : optionally followed by more digits \) : stop saving in container '\4' ~ : end of search pattern, start of substitution Code:
<irq nr='\1' dev='\2' total="\3" rate="\4" />~ <irq : 2 leading blanks and the text '<irq ' nr='\1' : the string 'nr=', a single quote, contents of container '\1', a single quote and blank dev='\2' : the string 'dev=', a single quote, contents of container '\2', a single quote and blank total="\3" : the string 'total=', a double quote, contents of container '\3', a double quote and blank rate="\4" : the string 'rate=', a double quote, contents of container '\4', a double quote and blank /> : the string '/>' closing the XML element 'irq' ~ : end of replacement pattern Code:
$ sed -ne '11p' vmstat2xml.sed >cmd-2 $ sed -f cmd-2 vmstat.txt interrupt total rate <irq nr='14' dev='pciide0' total="179284" rate="0" /> <irq nr='11' dev='uhci0' total="0" rate="0" /> <irq nr='10' dev='xl0' total="5115342" rate="2" /> [snip] <irq nr='9' dev='mpu0' total="0" rate="0" /> <irq nr='0' dev='clock' total="243870818" rate="99" /> <irq nr='8' dev='rtc' total="312161132" rate="127" /> Total 566212309 232 Code:
13 ${ 14 s~^[Tt]otal *\([0-9][0-9]*\) *\([0-9][0-9]*\)~ <summary grandtotal='\1' grate='\2' />~ 15 a\ 16 </vmstat-i> 17 } The first command (line 14) is a search and replace command. Lines 15-16 is an append function, which simple glues a terminating '</vmstat-i>' to the end of the output. The search part: Code:
s~^[Tt]otal *\([0-9][0-9]*\) *\([0-9][0-9]*\)~ Sample text : 'Total 566212309 232' s : substitute function ~ : custom delimiter indicating start of the search pattern [Tt] : a 'T' or a 't' (an attempt of defensive programming) otal : the string 'otal' * : a space, optionally followed by more spaces /* the total number of interrupts */ \( : start saving in container '\1' [0-9] : a single digit [0-9]* : optionally followed by more digits \) : stop saving in container '\1' * : a space, optionally followed by more spaces /* the average rate of interrupts */ \( : start saving in container '\2' [0-9] : a single digit [0-9]* : optionally followed by more digits \) : stop saving in container '\2 ~ : end of search pattern, start of substitution Code:
~ <summary grandtotal='\1' grate='\2' />~ <summary : 2 leading blanks and the string ' <summary ' grandtotal='\1' : the string 'grandtotal=', a single quote, contents of container '\1', a single quote and blank grate='\2' : the string 'grate=', a single quote, contents of container '\2', a single quote and blank /> : the string '/>' closing the XML element 'summary' ~ : end of replacement pattern Code:
$ sed -ne 13,17p vmstat2xml.sed >cmd-3 $ sed -f cmd-3 vmstat.txt interrupt total rate irq14/pciide0 179284 0 irq11/uhci0 0 0 [snip] irq0/clock 243870818 99 irq8/rtc 312161132 127 <summary grandtotal='566212309' grate='232' /> <vmstat-i> 1.4 Dr. XML's part in the makeover Depending on the circumstances Dr. XML chooses one of the following procedures:
Code:
<?xml version='1.0' encoding='UTF-8' ?> <?xml-stylesheet href='vmstat-i.xsl' type='text/xsl' ?> <!-- generated by 'sed(1)' --> <vmstat-i> <irq nr='14' dev='pciide0' total="179284" rate="0" /> <irq nr='11' dev='uhci0' total="0" rate="0" /> <irq nr='10' dev='xl0' total="5115342" rate="2" /> <irq nr='12' dev='fxp0' total="4880752" rate="2" /> <irq nr='1' dev='pckbc0' total="4981" rate="0" /> <irq nr='7' dev='lpt0' total="0" rate="0" /> <irq nr='4' dev='pccom0' total="0" rate="0" /> <irq nr='3' dev='pccom1' total="0" rate="0" /> <irq nr='6' dev='fdc0' total="0" rate="0" /> <irq nr='5' dev='wss1' total="0" rate="0" /> <irq nr='9' dev='mpu0' total="0" rate="0" /> <irq nr='0' dev='clock' total="243870818" rate="99" /> <irq nr='8' dev='rtc' total="312161132" rate="127" /> <summary grandtotal='566212309' grate='232' /> </vmstat-i> 1.5 The XSL stylesheet from Dr. XSLT For the repeating cosmetic makeovers Dr. XSLT has created the following XSL stylesheet: Code:
1 <?xml version="1.0" encoding='UTF-8' ?> 2 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 3 4 <!-- $Id: vmstat-i.xsl,v 1.2 2008/08/26 23:40:43 j65nko Exp $ --> 5 6 <xsl:output 7 method='html' 8 omit-xml-declaration='no' 9 indent='yes' 10 standalone='yes' 11 doctype-public='-//W3C//DTD XHTML 1.0 Strict//EN' 12 doctype-system='http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd' 13 /> 14 15 <xsl:template match="/vmstat-i" > 16 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" > 17 <head> 18 <title>vmstat -i</title> 19 <style type="text/css" > 20 <xsl:call-template name="stylesheet"/> 21 </style> 22 </head> 23 <body> 24 <table> 25 <xsl:call-template name="table-header" /> 26 <xsl:apply-templates select="irq"> 27 <!-- sort by IRQ number low to high --> 28 <xsl:sort select='@nr' data-type='number' order='ascending' /> 29 <!-- with identical, shared IRQ, show highest total first --> 30 <xsl:sort select='@total' data-type='number' order='descending' /> 31 </xsl:apply-templates> 32 <xsl:call-template name="total" /> 33 </table> 34 </body> 35 </html> 36 </xsl:template> 37 38 <xsl:template match="irq"> 39 <tr> 40 <td class='nr'> <xsl:value-of select="@nr"/> </td> 41 <td class='text'> <xsl:value-of select="@dev"/> </td> 42 <td class='nr'> <xsl:value-of select="format-number(@total,'#,###')"/> </td> 43 <td class='nr'> <xsl:value-of select="format-number(@rate,'#,###')" /> </td> 44 </tr> 45 </xsl:template> 46 47 <xsl:template name="stylesheet" > 48 .nr { text-align: right; background-color: rgb(220,220,200); padding: .5em; } 49 .text { text-align: left; background-color: rgb(220,200,200); padding: .5em; } 50 .hr { text-align: right; background-color: silver ; padding: .5em; } 51 </xsl:template> 52 53 <xsl:template name="table-header" > 54 <tr> 55 <td class='hr' style="text-align: center" colspan='4' >I n t e r r u p t s</td> 56 </tr> 57 <tr> 58 <td class='hr'>IRQ</td> 59 <td class='hr'>Device</td> 60 <td class='hr'>Total</td> 61 <td class='hr'>Rate</td> 62 </tr> 63 </xsl:template> 64 65 <xsl:template name="total" > 66 <tr> 67 <td class='hr' colspan='2' >T o t a l</td> 68 <td class='hr'><xsl:value-of select='format-number(sum(//@total),"#,###")' /> </td> 69 <td class='hr'><xsl:value-of select='format-number(sum(//@rate), "#,###")' /> </td> 70 </tr> 71 </xsl:template> 72 73 </xsl:stylesheet> Code:
1 <?xml version="1.0" encoding='UTF-8' ?> 2 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 3 4 <!-- $Id: vmstat-i.xsl,v 1.2 2008/08/26 23:40:43 j65nko Exp $ --> The root element is 'xsl:stylesheet', which starts on line 2 and ends on line 73. The 'xmlns:xsl' attribute defines the version and the XSLT namespace and it's prefix 'xsl'. All XML elements prefixed with 'xsl' constitute the stylesheet. After the comment on line 4, containing the RCS revision identifier, follows the first stylesheet element 'xsl-output' Code:
6 <xsl:output 7 method='html' 8 omit-xml-declaration='no' 9 indent='yes' 10 standalone='yes' 11 doctype-public='-//W3C//DTD XHTML 1.0 Strict//EN' 12 doctype-system='http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd' 13 /> The 'doctype-public' and 'doctype-system' attributes tell the XSLT engine to produce the proper heading for XHTML strict: Code:
<DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
The template which matches the 'irq' element extracts the IRQ number, device name, interrupt total and rate from lines like '<irq nr='14' dev='pciide0' total="179284" rate="0" />'. Code:
38 <xsl:template match="irq"> 39 <tr> 40 <td class='nr'> <xsl:value-of select="@nr"/> </td> 41 <td class='text'> <xsl:value-of select="@dev"/> </td> 42 <td class='nr'> <xsl:value-of select="format-number(@total,'#,###')"/> </td> 43 <td class='nr'> <xsl:value-of select="format-number(@rate,'#,###')" /> </td> 44 </tr> 45 </xsl:template> Code:
15 <xsl:template match="/vmstat-i" > 16 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" > 17 <head> 18 <title>vmstat -i</title> 19 <style type="text/css" > 20 <xsl:call-template name="stylesheet"/> 21 </style> 22 </head> 23 <body> 24 <table> 25 <xsl:call-template name="table-header" /> 26 <xsl:apply-templates select="irq"> 27 <!-- sort by IRQ number low to high --> 28 <xsl:sort select='@nr' data-type='number' order='ascending' /> 29 <!-- with identical, shared IRQ, show highest total first --> 30 <xsl:sort select='@total' data-type='number' order='descending' /> 31 </xsl:apply-templates> 32 <xsl:call-template name="total" /> 33 </table> 34 </body> 35 </html> 36 </xsl:template> Lines 17-22 will produce the html 'head' tag. The CSS stylesheet is included by calling the named template 'stylesheet'. The html 'body' element is created in lines 23-34. This consist of a single 'table' composed by lines 24-33. After invoking the 'table-header' template, the XSLT engine is directed to execute the template matching 'irq' in line 26. The output of this template will be sorted by IRQ number in ascending order. In case of shared IRQ's, the one with the highest interrupts will be shown first. After the calculation of the grand totals in line 32, the 'table', 'body', and 'html' tags are properly closed in the remaining lines 33-35. 1.6 Applying the XSL stylesheet in a browser If a physical result file in HTML format is not needed, you can just load the 'vmstat-iz.xml' file into Firefox. The 'href' attribute of <?xml-stylesheet href='vmstat-i.xsl' type='text/xsl' ?> is enough for Firefox to perform the XSLT transformation on the fly. For the transformation inside a browser to work, the 'output method' really needs to to be html Code:
<xsl:output method='html' omit-xml-declaration='no' indent='yes' standalone='yes' doctype-public='-//W3C//DTD XHTML 1.0 Strict//EN' doctype-system='http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd' /> Point your browser to vmstat-iz.xml to find out whether your browser supports XSLT transformations on the fly,. For a local test, you have to make sure that the XSL stylesheet is in the same directory. If for some reason you want the stylesheet in another location then you will have to hack line 5 of the 'vmstat2xml.sed' file to produce the correct 'href'. If you expect to see the HTML code, by selecting the Firefox 'View page source" menu option, or by by pressing CTRL-U, you will be disappointed. All you will see is a a nicely coloured, version of the XML file. For a physical transformation result you will have to use a stand-alone XSLT processor, as discussed in the following two sections. 1.7 Using Xalan-c for the XSLT transformation Xalan comes in two flavours, one in C and one in Java. Both are available in FreeBSD ports as 'textproc/xalan-c-1.10.0' and 'textproc/xalan-j-2.7.0_2'. Code:
xalan-c-1.10.0 XSLT processor from the Apache XML Project Maintained by: ports@FreeBSD.org Requires: gettext-0.17_1, gmake-3.81_3, libiconv-1.11_1, xerces-c2-2.7.0 xalan-j-2.7.0_2 Apache XSLT processor for transforming XML documents Maintained by: hq@FreeBSD.org Requires: apache-ant-1.7.0_2, diablo-jdk-1.6.0.07.02, inputproto-1.4.2.1, javavmwrapper-2.3.2, kbproto-1.0.3, libICE-1.0.4_1,1, libSM-1.0.3_1,1, libX11-1.1.3_1,1, libXau-1.0.3_2, libXdmcp-1.0.2_1, libXext-1.0.3,1, libXi-1.1.3,1, libXp-1.0.0,1, libXt-1.0.5_1, libXtst-1.0.3_1, pkg-config-0.23_1, printproto-1.0.3, recordproto-1.13.2, xerces-j-2.9.0_2, xextproto-7.0.2, xproto-7.0.10_1 Also listed in: Java The following Makefile deals with that by using 'scp' to copy the out of date dependencies to a FreeBSD box named 'plato', and to invoke 'Xalan' via 'ssh'. Code:
# -- Makefile for applying XSLT stylesheets to XML sources using Xalan-c on a remote box # $Id: vmstat-makeover.xml,v 1.12 2008/09/12 04:00:10 j65nko Exp $ # -- source file definition in variable FILE and STYLESHEET # -- (without .xml and .xsl extension) # The '?=' means, assign these values only if not already defined # on the command line e.g. : $ make FILE=vmstat-makeover STYLESHEET=howto FILE ?= vmstat-iz STYLESHEET ?= vmstat-i # ------------ end of source file definitions SOURCE = ${FILE}.xml RESULT_HTML = ${FILE}.html STYLESTEET_HTML = ${STYLESHEET}.xsl STYLESHEET_XHTML= ${STYLESHEET}_XHTML.xsl TEMP = ${FILE}_temp.html # --- dependencies ${RESULT_HTML}: ${TEMP} # -- remove empty 'xmlns' attributes which prevent validation by http://validator.w3.org/ sed -e 's/xmlns=""//g' -e "s/xmlns=''//g" ${.ALLSRC} >${.TARGET} # -- copy Out Of Date dependencies to box plato, running FreeBSD and Xalan-c # -- For some reason Xalan complains if there is no space between the # -- '-i' (amount of indentation) and the number of indentation spaces ${TEMP}: ${SOURCE} ${STYLESHEET_XHTML} @echo TARGET ${.TARGET} has these out of date dependencies: ${.OODATE} scp ${.OODATE} j65nko@plato:ARTICLES ssh j65nko@plato 'cd ARTICLES ; Xalan -i 2 ${.ALLSRC}' >${.TARGET} # --------------------------------------------------------------------------------------- # The html output method is required to have the XML file transformed inside a browser, # This however does not produce valid XML. # See http://www.w3.org/TR/xslt#section-HTML-Output-Method # For XHTML strict (HTML redefined into XML) we have to change the output method # from 'html' to 'xml'. # So it is convenient to standardize on html output, and only change to XML for producing # XHTML by an external stand-alone XSLT engine/processor ${STYLESHEET_XHTML}: ${STYLESTEET_HTML} @echo TARGET ${.TARGET} has these out of date dependencies: ${.OODATE} # change output method to 'xml' sed -e "/<xsl:output/,/\/>/s/method='html'/method='xml'/" ${.ALLSRC} >${.TARGET} # --------------------------------------------------------------------------------------- # sed -e "/<xsl:output/,/\/>/s/method='html'/method='xml'/" ${.ALLSRC} >${.TARGET} # # /<xsl:output/ : the line nr (address) with the start of the 'xsl:output' element # , : separating first address of second address # /\/>/ : the line nr (address) of the closing '/>' of the 'xsl:output' element # : we now have a line number range as the source for the search and replace: # s/method='html'/method='xml'/ # # s : search and replace command # /method='html'/ : search for the string 'method='html' # /method='xml'/ : and replace with '/method='xml' # # --------------------------------------------------------------------------------------- clean: rm ${STYLESHEET_XHTML} ${TEMP} ${RESULT_HTML} show: ls -ltT Alternatively, you can use the '-o' option to specify the output file. Code:
$ Xalan ? Xalan version 1.8.0. Xerces version 2.6.0. Usage: Xalan [options] source stylesheet Options: -a Use xml-stylesheet PI, not the 'stylesheet' argument -e encoding Force the specified encoding for the output. -i integer Indent the specified amount. -m Omit the META tag in HTML output. -o filename Write output to the specified file. -p name expression Sets a stylesheet parameter. -t Display timing information. -u Disable escaping of URLs in HTML output. -? Display this message. -v Validates source documents. - A dash as the 'source' argument reads from stdin. ('-' cannot be used for both arguments.) Code:
$ make TARGET vmstat-i_XHTML.xsl has these out of date dependencies: vmstat-i.xsl # change output method to 'xml' sed -e "/<xsl:output/,/\/>/s/method='html'/method='xml'/" vmstat-i.xsl >vmstat-i_XHTML.xsl TARGET vmstat-iz_temp.html has these out of date dependencies: vmstat-iz.xml vmstat-i_XHTML .xsl scp vmstat-iz.xml vmstat-i_XHTML.xsl j65nko@plato:ARTICLES vmstat-iz.xml 100% 870 0.9KB/s 00:00 vmstat-i_XHTML.xsl 100% 2343 2.3KB/s 00:00 ssh j65nko@plato 'cd ARTICLES ; Xalan -i 2 vmstat-iz.xml vmstat-i_XHTML.xsl' >vmstat-iz_temp.html # -- remove empty 'xmlns' attributes which prevent validation by http://validator.w3.org/ sed -e 's/xmlns=""//g' -e "s/xmlns=''//g" vmstat-iz_temp.html >vmstat-iz.html Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> <head> <title>vmstat -i</title> <style type="text/css"> .nr { text-align: right; background-color: rgb(220,220,200); padding: .5em; } .text { text-align: left; background-color: rgb(220,200,200); padding: .5em; } .hr { text-align: right; background-color: silver ; padding: .5em; } </style> </head> <body> <table> <tr > <td class="hr" style="text-align: center" colspan="4">I n t e r r u p t s</td> </tr> <tr > <td class="hr">IRQ</td> <td class="hr">Device</td> <td class="hr">Total</td> <td class="hr">Rate</td> </tr> <tr > <td class="nr">0</td> <td class="text">clock</td> <td class="nr">243,870,818</td> <td class="nr">99</td> </tr> [snipped] <tr > <td class="hr" colspan="2">T o t a l</td> <td class="hr">566,212,309</td> <td class="hr">230</td> </tr> </table> </body> </html> 1.8 Using Sablotron for the XSLT transformation Sablotron is available in the OpenBSD ports system. Code:
Version: 1.0.1p3, Package name: sablotron-1.0.1p3 Maintained by: Anil Madhavapeddy Required to run: [converters/libiconv] Required to build: [devel/gmake] [devel/libtool] [textproc/p5-XML-Parser] Code:
Sablot-1.0.3 XML toolkit implementing XSLT 1.0, XPath 1.0 and DOM Level2 Maintained by: skv@FreeBSD.org Requires: expat-2.0.1, gettext-0.17_1, gmake-3.81_3, libiconv-1.11_1, libtool-1.5.26, p5-XML-Parser-2.36, perl-5.8.8_1 Note that the order of the source files is different from 'Xalan' See sabcmd(1) for more information. The 'Makefile' for Sablotron: Code:
# -- Makefile for applying XSLT stylesheets to XML sources using Sablotron # -- $Id: vmstat-makeover.xml,v 1.12 2008/09/12 04:00:10 j65nko Exp $ # -- source file definition in variable FILE and STYLESHEET # -- (without .xml and .xsl extension) # The '?=' means, assign these values only if not already defined # on the command line e.g. : $ make FILE=vmstat-makeover STYLESHEET=howto FILE ?= vmstat-iz STYLESHEET ?= vmstat-i # ------------ end of source file definitions SOURCE = ${FILE}.xml RESULT_HTML = ${FILE}.html STYLESTEET_HTML = ${STYLESHEET}.xsl STYLESHEET_XHTML= ${STYLESHEET}_XHTML.xsl TEMP = ${FILE}_temp.html # --- dependencies ${RESULT_HTML}: ${TEMP} # -- remove empty 'xmlns' attributes which prevent validation by http://validator.w3.org/ sed -e 's/xmlns=""//g' -e "s/xmlns=''//g" ${.ALLSRC} >${.TARGET} ${TEMP}: ${STYLESHEET_XHTML} ${SOURCE} @echo TARGET ${.TARGET} has these out of date dependencies: ${.OODATE} sabcmd ${.ALLSRC} >${.TARGET} # --------------------------------------------------------------------------------------- # The html output method is required to have the XML file transformed inside a browser, # This however does not produce valid XML. # See http://www.w3.org/TR/xslt#section-HTML-Output-Method # For XHTML strict (HTML redefined into XML) we have to change the output method # from 'html' to 'xml'. # So it is convenient to standardize on html output, and only change to XML for producing # XHTML by an external stand-alone XSLT engine/processor ${STYLESHEET_XHTML}: ${STYLESTEET_HTML} @echo TARGET ${.TARGET} has these out of date dependencies: ${.OODATE} # change output method to 'xml' sed -e "/<xsl:output/,/\/>/s/method='html'/method='xml'/" ${.ALLSRC} >${.TARGET} # --------------------------------------------------------------------------------------- # sed -e "/<xsl:output/,/\/>/s/method='html'/method='xml'/" ${.ALLSRC} >${.TARGET} # # /<xsl:output/ : the line nr (address) with the start of the 'xsl:output' element # , : separating first address of second address # /\/>/ : the line nr (address) of the closing '/>' of the 'xsl:output' element # : we now have a line number range as the source for the search and replace: # s/method='html'/method='xml'/ # # s : search and replace command # /method='html'/ : search for the string 'method='html' # /method='xml'/ : and replace with '/method='xml' # # --------------------------------------------------------------------------------------- clean: rm ${STYLESHEET_XHTML} ${TEMP} ${RESULT_HTML} show: ls -ltT Code:
$ make TARGET vmstat-i_XHTML.xsl has these out of date dependencies: vmstat-i.xsl # change output method to 'xml' sed -e "/<xsl:output/,/\/>/s/method='html'/method='xml'/" vmstat-i.xsl >vmstat-i_XHTML.xsl TARGET vmstat-iz_temp.html has these out of date dependencies: vmstat-i_XHTML.xsl vmstat-iz.xml sabcmd vmstat-i_XHTML.xsl vmstat-iz.xml >vmstat-iz_temp.html Warning [code:93] [URI:file:///home/j65nko/Makeover/Sablotron/vmstat-iz.xml] [line:20] unsupported language 'en' Warning [code:93] [URI:file:///home/j65nko/Makeover/Sablotron/vmstat-iz.xml] [line:20] unsupported language 'en' # -- remove empty 'xmlns' attributes which prevent validation by http://validator.w3.org/ sed -e 's/xmlns=""//g' -e "s/xmlns=''//g" vmstat-iz_temp.html >vmstat-iz.html 1.9 Resources
1.10 Epilogue Dr. XML and Dr. XSLT have developed similar beautifying procedures for pfclt -sl and df -i output. They intend to report about these procedures in the following months. $Id: vmstat-makeover.xml,v 1.12 2008/09/12 04:00:10 j65nko Exp $
$Id: vbul-html.xsl,v 1.14 2008/09/12 03:44:16 j65nko Exp $
__________________
You don't need to be a genius to debug a pf.conf firewall ruleset, you just need the guts to run tcpdump Last edited by J65nko; 1st December 2011 at 09:53 PM. Reason: silenceisdefeat.org ->silenceisdefeat.com |
|
|||
Download files and guide in HTML format
Attached is a *.tgz archive containing all files discussed in this guide. As a bonus the complete guide in HTML format, for easier scrollbar-less viewing, studying or printing.
Extract the files with Code:
$ tar xvzf vmstat-makeover.tgz Makeover Makeover/Xalan Makeover/Xalan/vmstat-iz.xml Makeover/Xalan/Makefile Makeover/Xalan/vmstat-i.xsl Makeover/Sablotron Makeover/Sablotron/Makefile Makeover/Sablotron/vmstat-iz.xml Makeover/Sablotron/vmstat-i.xsl Makeover/vmstat-iz.xml Makeover/vmstat2xml.sed Makeover/vmstat-i.xsl Makeover/vmstat.txt Makeover/vmstat-makeover.html Code:
$ ls -lR Makeover/ total 120 drwxr-xr-x 2 j65nko j65nko 512 Sep 11 04:54 Sablotron drwxr-xr-x 2 j65nko j65nko 512 Sep 11 04:53 Xalan -rw-r--r-- 1 j65nko j65nko 2344 Sep 8 04:23 vmstat-i.xsl -rw-r--r-- 1 j65nko j65nko 870 Sep 11 02:06 vmstat-iz.xml -rw-r--r-- 1 j65nko j65nko 46603 Sep 12 06:31 vmstat-makeover.html -rw-r--r-- 1 j65nko j65nko 705 Sep 11 04:55 vmstat.txt -rwxr-xr-x 1 j65nko j65nko 441 Sep 11 02:06 vmstat2xml.sed Makeover/Sablotron: total 8 -rw-r--r-- 1 j65nko j65nko 2587 Sep 11 02:10 Makefile lrwxr-xr-x 1 j65nko j65nko 15 Sep 11 02:19 vmstat-i.xsl -> ../vmstat-i.xsl lrwxr-xr-x 1 j65nko j65nko 16 Sep 11 02:14 vmstat-iz.xml -> ../vmstat-iz.xml Makeover/Xalan: total 8 -rw-r--r-- 1 j65nko j65nko 3058 Sep 11 02:15 Makefile lrwxr-xr-x 1 j65nko j65nko 15 Sep 11 02:20 vmstat-i.xsl -> ../vmstat-i.xsl lrwxr-xr-x 1 j65nko j65nko 16 Sep 11 02:14 vmstat-iz.xml -> ../vmstat-iz.xml Last edited by J65nko; 13th September 2008 at 09:44 PM. Reason: typo |
Tags |
make, makefile, regular expressions, sablotron, sed, vmstat, xalan, xhtml, xml, xslt |
Thread Tools | |
Display Modes | |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
dwm status bar won't display apm output | asemisldkfj | General software and network | 6 | 16th August 2009 11:07 PM |
strange dmesg output | gosha | OpenBSD General | 4 | 11th March 2009 01:10 PM |
Digital sound output | Zodox | FreeBSD General | 5 | 12th November 2008 02:21 PM |
C and file input/output | 18Googol2 | Programming | 3 | 20th August 2008 04:02 PM |
strange security run output | deadeyes | FreeBSD Security | 5 | 2nd July 2008 04:51 PM |