Print elements of an RSS feed as columns

0

I am trying to output the values of certain elements in an RSS feed as columns. The structure of an the RSS feed in question is this (abbreviated):

$ xmlstarlet el ~/tmp/spotn-rss-20140323 | sort -u 

rss/channel/title
rss/channel/item/content
rss/channel/item/description
rss/channel/item/link
rss/channel/item/pubDate
rss/channel/item/title

After applying an xmlstarlet sel command with a template I would like to see a list of item titles and their publication dates arranged in columns.

$ xmlstarlet sel -t \
    -v rss/channel/item/title \
    -v rss/channel/item/pubDate -n ~/tmp/spotn-rss-20140323

Desired output:               Actual output:

title1:pubDate1               title1
title2:pubDate2               title2
title3:pubDate3               title3
 (...)                         (...)
                              pubDate1
                              pubDate2
                              pubDate3
                               (...)

This problem seem rather trivial, and I thought it might be a good idea to check the user guide. As it turn out, the hello world example with an .xls stylesheet provides means to acheive the desired effect with little effort:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:param name="inputFile">-</xsl:param>
<xsl:template match="/">
  <xsl:call-template name="t1"/>
</xsl:template>
<xsl:template name="t1">
    <xsl:for-each select="rss/channel/item">
    <xsl:value-of select="title" />^<xsl:value-of select="pubDate" />;
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

I get the desired output with the transform command, but I find this approach rather cumbersome because xml/xls is very wordy. My objective is to quickly look at some elements in the xml, I don't want to write a ~450 character stylesheet just for that.

$ xmlstarlet tr  /home/jaroslav/tmp/spotn-rss-style.xls \
          /home/jaroslav/tmp/spotn-rss-20140323 |
  column -ts^

Test                                         Thu, 20 Mar 2014 18:58:11 +0000;
Assisterende borer – Songa Offshore          Thu, 20 Mar 2014 12:48:03 +0000;
Maskinsjef                                   Thu, 20 Mar 2014 10:23:16 +0000;
Maskinsjefer/Motorpassere                    Sun, 16 Mar 2014 16:37:15 +0000;
Skipsfører                                   Sun, 16 Mar 2014 16:30:19 +0000;
Tilkallingsvikarar matros                    Thu, 13 Mar 2014 03:15:55 +0000;
Matros                                       Wed, 12 Mar 2014 13:05:57 +0000;
1. styrmann                                  Tue, 11 Mar 2014 05:44:31 +0000;
Overstyrmann Scan Trans                      Tue, 04 Mar 2014 06:35:29 +0000;
(...)

It would be most useful if there was a way to concatenate two values from each <item> element in <channel> on a separate line without resorting to xls stylesheets or external stream editors such as sed and awk.

Ярослав Рахматуллин

Posted 2014-03-23T13:00:43.157

Reputation: 9 076

Answers

0

The xls stylesheet provides a clue.

The original example stylesheet has xsl:for-each select="/" while the one in the question has
select="rss/channel/item". Using the same logic, just match rss/channel/item and print each of title, pubDate with a delimiter:

$ xmlstarlet sel -t           \
     -m rss/channel/item      \
        -v title -o '^'       \
        -v pubDate            \
        -n ~/tmp/spotn-rss-20140323 |
  column -ts^

Result

 Test                                          Thu, 20 Mar 2014 18:58:11 +0000
 Assisterende borer – Songa Offshore           Thu, 20 Mar 2014 12:48:03 +0000
 Borer – Boring – Songa Offshore               Thu, 20 Mar 2014 12:42:57 +0000
 Hydrauliker – Songa Offshore                  Thu, 20 Mar 2014 12:34:56 +0000

Ярослав Рахматуллин

Posted 2014-03-23T13:00:43.157

Reputation: 9 076