As suggested by @thatotherguy, you probably want to do this using something like XSLT instead of Bash. You can parse XML with Bash , but it will probably be quite complicated.
Following @thatotherguy's suggestion, you can create an XSLT stylesheet that looks something like this:
<?xml version="1.0" encoding="iso-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:param name="character"/> <xsl:output method="html" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:variable name="vLower" select="'abcdefghijklmnopqrstuvwxyz'"/> <xsl:variable name="vUpper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/> <xsl:template name="capitalize"> <xsl:param name="string"/> <xsl:value-of select= "concat(translate(substring( $string, 1, 1), $vLower, $vUpper), substring($string, 2) ) "/> </xsl:template> <xsl:template match="/"> <xsl:if test="string-length($character) = 0 or not(//literal[. = $character])"> <xsl:message terminate="yes">ERR: No input character given.</xsl:message> </xsl:if> <xsl:apply-templates select="characters/character[literal[. = $character]]"/> </xsl:template> <xsl:template match="character"> <xsl:text disable-output-escaping='yes'><!DOCTYPE html> </xsl:text> <html> <head/> <body> <table> <tbody> <xsl:apply-templates/> </tbody> </table> </body> </html> </xsl:template> <xsl:template match="literal"> <caption> <xsl:value-of select="."/> </caption> </xsl:template> <xsl:template match="stroke_count"> <tr> <td> <xsl:call-template name="capitalize"> <xsl:with-param name="string" select="translate(local-name(), '_', ' ')"/> </xsl:call-template> </td> <td><xsl:value-of select="."/></td> </tr> </xsl:template> <xsl:template match="misc | reading_meaning | rmgroup"> <xsl:apply-templates/> </xsl:template> <xsl:template match="reading | meaning"> <tr> <td> <xsl:call-template name="capitalize"> <xsl:with-param name="string" select="local-name()"/> </xsl:call-template> <xsl:apply-templates select="@r_type"/> </td> <td> <xsl:value-of select="."/> </td> </tr> </xsl:template> <xsl:template match="@r_type"> <xsl:value-of select="concat(' ', '(', ., ')')"/> </xsl:template> </xsl:stylesheet>
Let's say you have a file called characters.xml :
<characters> <character> <literal>ζ΅</literal> <misc> <stroke_count>10</stroke_count> </misc> <reading_meaning> <rmgroup> <reading r_type="ja_on">γ±γ€</reading> <reading r_type="ja_on">γ¨</reading> <reading r_type="ja_kun">γγ.γ</reading> <reading r_type="ja_kun">γγ.γΏ</reading> <meaning>favor</meaning> <meaning>blessing</meaning> <meaning>grace</meaning> <meaning>kindness</meaning> </rmgroup> </reading_meaning> </character> </characters>
You can run kanjilookup.xsl on it using XMLStarlet as follows:
xml tr kanjilookup.xsl -s character=ζ΅ characters.xml
This will create an HTML table that looks like this (after a pretty-printed one):
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <table> <tbody> <caption>ζ΅</caption> <tr> <td>Stroke count</td> <td>10</td> </tr> <tr> <td>Reading (ja_on)</td> <td>γ±γ€</td> </tr> <tr> <td>Reading (ja_on)</td> <td>γ¨</td> </tr> <tr> <td>Reading (ja_kun)</td> <td>γγ.γ</td> </tr> <tr> <td>Reading (ja_kun)</td> <td>γγ.γΏ</td> </tr> <tr> <td>Meaning</td> <td>favor</td> </tr> <tr> <td>Meaning</td> <td>blessing</td> </tr> <tr> <td>Meaning</td> <td>grace</td> </tr> <tr> <td>Meaning</td> <td>kindness</td> </tr> </tbody> </table> </body> </html>
Of course, you will need to modify the XSLT stylesheets to suit your needs.