Showing posts with label xmlstarlet. Show all posts
Showing posts with label xmlstarlet. Show all posts

2009-08-26

3 ways to re-indent XML

There is a lot of data in XML formats, but often it's hardly readable: written by programs for programs, everything in one line. Indenting XML automatically helps to read such files.

1. Using XSLT
I have a file with an XSL transformation:
<xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:param name="indent-increment" select="'   '" />

<xsl:template match="*">
   <xsl:param name="indent" select="'&#xA;'"/>

   <xsl:value-of select="$indent"/>
   <xsl:copy>
     <xsl:copy-of select="@*" />
     <xsl:apply-templates>
       <xsl:with-param name="indent"
            select="concat($indent, $indent-increment)"/>
     </xsl:apply-templates>
     <xsl:value-of select="$indent"/>
   </xsl:copy>
</xsl:template>

<xsl:template match="comment()|processing-instruction()">
   <xsl:copy />
</xsl:template>

<!-- WARNING: this is dangerous. Handle with care -->
<xsl:template match="text()[normalize-space(.)='']"/>

</xsl:stylesheet>
I found it here. There are also some other variants.

In addition to XSLT file, I have a one-line script which actually runs this transformation. I use xmlstarlet, which is a nice CLI utility to deal with XML.

#!/bin/sh
xmlstarlet tr ~/bin/indent-xml.xsl
Run this script as:
$ xmlindent < original.xml
Along with xmlstarlet you can use other XSL processors. For example, xsltproc should work too.
2. Using xmllint
Inside libxml2-utils package (Debian/Ubuntu) there is an XML validator tool xmllint. It can also reformat (indent) XML:
$ xmllint --format original.xml
This must be even easier.
3. xmlindent
xmlindent is a pure C utility with almost no dependencies. It is intended to do just what it is named: indent XML. I didn't try it.

Прочесть по-русски

2008-06-09

antiodt: view OpenOffice documents as plain text

I don't like launching heavy office applications just to read a file. And there are antiword and wv to read MSWord *.doc files, unrtf to read RTF, and pdftotext to read PDF. Only open, ISO standard, ODT (OpenDocument, produced by OpenOffice) cannot be read that way. o3read seems to be useless for the new ODT files.

So, this is a one-and-half-line script I use to view OpenOffice files quickly from the shell prompt (antiodt):

#!/bin/sh
unzip -p "$1" content.xml | \
xmlstarlet sel -N text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" \
  -T -t -m '//text:p' -v . -n | less
Any ODT is just a normal ZIP archive with an XML file with all the contents. I used xmlstarlet to extract text paragraphs from that XML. Certainly, all formatting is lost, but it is fast.:
$ antiodt document.odt
I got an idea from here.

Update 2009-09-23: To convert ODT to plain text and preserve some formatting, use odt2txt.py script. It converts ODT to Markdown.

This post in Russian: antiodt: просмотр документов OpenOffice в виде простого текста

2008-02-05

How to parse RSS 2.0 in bash

It is quite easy to use information from RSS feeds in bash scripts. I use xmlstarlet to work with XML in the shell. For example, to print the latest titles and links from my RSS feed, I can do:
RSS_URL=http://feeds.feedburner.com/usefreetools
wget ${RSS_URL} -O - 2>/dev/null | \
xmlstarlet sel -t -m "/rss/channel/item" \
  -v "guid" -n -v "pubDate" -n -v "title" -n -v "link" -n -n
Alternatively, I can use curl -g ${RSS_URL} -s instead of wget. I could have added -v "description" to see the contents of my posts.