Formatting Text (SOLVED --ish)

  • Platform information:
    • Hardware: Virtual with 4gb ram
    • OS: Windows 2008R2 x 64
    • Java Runtime Environment:1.8.161
    • openHAB version:2.2

I would like to include News with my weather. I have created item:

String 	 RSS_Test3   "TestText [%1:$s]"	{http="<[http://feeds.bbci.co.uk/news/world/us_and_canada/rss.xml:6000:XSLT(Test.xsl)]"}

My XLSM Transform:

<?xml version="1.0"?>
<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

    <xsl:output indent="no" method="text" encoding="UTF-8" standalone="yes" omit-xml-declaration="yes"/>
    <xsl:template match="/">
    	<xsl:for-each select="//rss/channel/item">
    			<xsl:text><b>Title:</b> </xsl:text>
    			<xsl:value-of select="title"/>
    			<xsl:text><br /><b>Description:</b> </xsl:text>
    			<xsl:value-of select="description"/>
    			<xsl:text><br /><br /><br /></xsl:text>
    	</xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

This successfully gets all of the XML items from this RSS news feed. As you may be able to guess, I would like to get this feed in an HTML format. In that way, it would be all nice and pretty (and easily read.) I have gone around and around, but nothing I have done gives any HTML output. I use HABPanel with a template:

<div ng-init="ServerPath='http://localhost:8080/static'; IconSet='Moon'">
<link rel="stylesheet" type="text/css" href="{{ServerPath}}/layouts/default.css" />
</div>
<div>
  <h2>News</h2>
  {{itemValue('RSS_Test3')}}
</div>

Everything I have tried results in the same thing. Unformatted block of text. I don’t use the built in RSS feed because it only gives 1 item – the latest. Any hints would be most welcome. Thanks!

Title:Russia-Trump inquiry: Russians charged over US 2016 election tampering Description:The named Russians are indicted along with three Russian companies by special counsel Robert Mueller. Title:Florida school shooting: FBI mishandled tip on gunman’s ‘desire to kill’ Description:US Attorney General Jeff Sessions has ordered a review the bureau’s processes after the misstep. Title:Mitt Romney launches Utah Senate campaign with dig at Trump Description:The ex-presidential nominee laments Washington is sending “a message of exclusion” to immigrants. Title:White House refuses to release photo of Trump gun law repeal Description:Despite repeated media requests, the image of Mr Trump revoking a gun control law stays under wraps. Title:How a US grandmother foiled an alleged school shooting plot Description:When a Washington state gran found her grandson’s troubling journal entries, she called the police. Title:New York ex-teacher and twin arrested for bomb-making Description:The city’s police believe an ex-teacher and his brother paid students to handle gunpowder. Title:Trump-Russia: Steve Bannon questioned in Mueller inquiry Description:Steve Bannon, a former top adviser to Donald Trump, reportedly spent 20 hours with investigators. Title:Florida shooting: ‘We watched gunman kill our friends’ Description:Two students who hid under a desk as a gunman fired at their classmates describe their ordeal. Title:Immigration effort to protect Dreamers collapses in US Senate Description:The Senate falls short of the 60 votes needed to pass any of four proposals brought to the floor. Title:Winter Olympics: Fans leap to Nathan Chen’s defence Description:After Nathan Chen’s uncharacteristic tumble in an Olympic skating event, fans jumped to his rescue Title:Winter Olympics: Mikaela Shiffrin fourth in slalom as Frida Hansdotter wins Description:Sweden’s Frida Hansdotter wins the women’s slalom as favourite Mikaela Shiffrin misses out on a second gold in Pyeongchang. Title:Jennifer Aniston and Justin Theroux announce separation Description:The couple, who were married in 2015, say the decision is mutual and was “lovingly made”. Title:Texas couple propose at same moment Description:The moment Tori and Berkley popped the question at the same time has gone viral. Title:Transgender woman breastfeeds baby in first recorded case, study says Description:She was able to produce enough milk to be the baby’s only food source for the first six weeks, a study says. Title:Toronto fire fighter who went missing in NY found in California Description:Police say Danny Filippidis can’t remember much about how he went from a ski hill to Sacramento. Title:Florida shooting: Who are the victims? Description:Football coach Aaron Feis, who was shot while shielding pupils, was among those killed on Wednesday. Title:Nikolas Cruz: Depressed loner ‘crazy about guns’ Description:Students at the school described Nikolas Cruz, 19, as an “outcast” known for making threats. Title:Florida shooting: Senators singled out over gun lobby funds Description:Politicians sending condolences to Florida victims criticised by screenwriter Bess Kalb. Title:‘Guns and survivalists, but no school until I was 17’ Description:Tara’s fundamentalist family in rural Idaho would not let her go to school, but she got a PhD from Cambridge. Title:How pastry chef training helps people with disabilities Description:Unemployment for disabled adults is double the US average but a bakery in Maryland is trying to change that. Title:Chloe Kim: Why do some people get ‘hangry’? Description:Kim was ‘hangry’ before winning a Winter Olympic gold medal. Why does hunger make people angry? Title:US Judge dismisses Taylor Swift ‘haters’ case as too ‘banal’ Description:The phrase “haters gonna hate” cannot be copyrighted, rules the judge in a case against Taylor Swift.

Still no luck with this. Although, I have made some kludgey progress. Instead of using HTML tags for line breaks I add a bunch of non-breaking spaces. Thus, it is much more readable. (using &#160; rather than &nbsp; which breaks it.)

If you would like to see that, here it is:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output indent="no" method="text" encoding="UTF-8" standalone="yes" omit-xml-declaration="yes"/>
    <xsl:template match="/">
    	<xsl:for-each select="//rss/channel/item">
    			<xsl:text>Date: </xsl:text>
    			<xsl:value-of select="pubDate"/>
    			<xsl:text> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Title: </xsl:text>
    			<xsl:value-of select="title"/>
    			<xsl:text> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Description: </xsl:text>
    			<xsl:value-of select="description"/>
    			<xsl:text> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Link: </xsl:text>
    			<xsl:value-of select="link"/>
    			<xsl:text> &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; </xsl:text>
    	</xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Like I said, I wanted to include news with my weather. What better way than to use an RSS feed? So, if you too want to include some news with your weather, you can do what I did. (There may be more elegant ways, but I haven’t taken the time to polish it.)

First, you will need to add the “HTTP” binding. The RSS binding only gives you the first article (and the number of articles you are missing). You will need several items:

/* RSS Transform  */
String 	 RSS_Feed1   "[%s]"	{http="<[http://feeds.bbci.co.uk/news/world/us_and_canada/rss.xml:60000:XSLT(BBCNewsTitle.xsl)]"}
String 	 RSS_Feed2   "[%s]"

/* RSS Articles */
Group 	 RSS_Articles
String 	 RSS_Article0 "[%s]"	(RSS_Articles)
String 	 RSS_Article1 "[%s]"	(RSS_Articles)
String 	 RSS_Article2 "[%s]"	(RSS_Articles)
String 	 RSS_Article3 "[%s]"	(RSS_Articles)
String 	 RSS_Article4 "[%s]"	(RSS_Articles)
String 	 RSS_Article5 "[%s]"	(RSS_Articles)
String 	 RSS_Article6 "[%s]"	(RSS_Articles)
String 	 RSS_Article7 "[%s]"	(RSS_Articles)
String 	 RSS_Article8 "[%s]"	(RSS_Articles)
String 	 RSS_Article9 "[%s]"	(RSS_Articles)

The first item gets all of the items from the RSS feed. That feed will need to go through an XSLT transform.

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output indent="no" method="text" encoding="UTF-8" standalone="yes" omit-xml-declaration="yes"/>
    <xsl:template match="/">
    	<xsl:for-each select="//rss/channel/item">
    			<xsl:value-of select="title"/>
    			<xsl:text>##11##;</xsl:text>
    			<xsl:value-of select="link"/>
    			<xsl:text>##11##;</xsl:text>
    	</xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

RSS feeds come in a standard form. I use the “title” and the “link” for my viewing. I may add “pubdate” or “description” in some fashion later. The ##11##; is added and will be used as a delimiter between each part of the news articles. Now that we have a list of articles we will need some rules to transform them into a format that can be used in a template for our HABPanel.

rule "Removing_Unwanted_Characters_RSS_Feed"
when
  System started or
  Item RSS_Feed1 changed
then
	//Convert the RSS_Feed into a string that can be manipulated
	val String strTemp = RSS_Feed1.state.toString
	//Replace all apostrophes with their HTML equivalent
	strTemp = strTemp.replaceAll("'", "&lsquo;")
	//Replace our delimiter with an apostrophe  (Only a single character can be used in the "Split" funcion)
	strTemp = strTemp.replaceAll("##11##;", "'")
	//Instead of writing over RSS_Feed1, I create a second string item and write to it.
	RSS_Feed2.postUpdate(strTemp)
	//Log our success
	logInfo("TextChange.Rules", "RSS_Feed1 changed")
end
rule "Establishing_Articles_RSS_Feed"
when
  System started or
  Item RSS_Feed2 changed
then
	//Convert the RSS_Feed into a string that can be manipulated
	val String strTemp = RSS_Feed2.state.toString
	//Split will create a list of items that we can obtain via an index
	val list = strTemp.split("'")
	//Assign label the URL from the feed
	RSS_Article0.label = list.get(1)
	//Assign the state to the Title of the article
	RSS_Article0.postUpdate(list.get(0))
	RSS_Article1.label = list.get(3)
	RSS_Article1.postUpdate(list.get(2))
	RSS_Article2.label = list.get(5)
	RSS_Article2.postUpdate(list.get(4))
	RSS_Article3.label = list.get(7)
	RSS_Article3.postUpdate(list.get(6))
	RSS_Article4.label = list.get(9)
	RSS_Article4.postUpdate(list.get(8))
	RSS_Article5.label = list.get(11)
	RSS_Article5.postUpdate(list.get(10))
	RSS_Article6.label = list.get(13)
	RSS_Article6.postUpdate(list.get(12))
	RSS_Article7.label = list.get(15)
	RSS_Article7.postUpdate(list.get(14))
	RSS_Article8.label = list.get(17)
	RSS_Article8.postUpdate(list.get(16))
	RSS_Article9.label = list.get(19)
	RSS_Article9.postUpdate(list.get(18))
	//Log our success
	logInfo("TextChange.Rules", "Articles Added")
end


rule "Changing_Articles_For_More_Readability"
when
  System started or
  Item RSS_Article9 changed
then
	//We will need a temporary string value to manipulate.
	val String strTemp = ""
	//We have a group of RSS_Articles and we want to remove the HTML apostrophe and replace it with the actual apostrophe.  
	//Because items do not recognize HTML, we need to convert it.
	RSS_Articles.members.forEach[ i | strTemp=i.state.toString ; strTemp = strTemp.replaceAll("&lsquo;", "'") ; i.postUpdate(strTemp)]
	//Log our success
	logInfo("TextChange.Rules", "Replaced apostrophes")

end

Now we have our items all formatted up nice, we just need to display them in a template or whatever. I use HABPanel, so I use the following template to display my news.

<div ng-init="ServerPath='http://localhost:8080/static'; IconSet='Moon';">
	<link rel="stylesheet" type="text/css" href="{{ServerPath}}/layouts/default.css" />
</div>
<br /><br />
<h2>News</h2>
<div ng-repeat="Article in itemsInGroup('RSS_Articles') track by $index">
          <p>{{$index+1}}) <a href="{{Article.label}}" target="_Article">{{Article.state}}</a></p>
</div>

It uses the articles “Title” and if you click on the title, it will take you to the link of the new item. it works pretty nicely. I hope you find it helpful!

Hi

I’m really sorry that I didn’t see your post about this sooner, it’s almost exactly what I was trying to achieve.

My solution looks like this

I did wonder if I used the full description from the BBC RSS feed I could get data like wind direction, sun exposure etc.

The big difference between what you did and what I did is that I wanted multiple articles from an RSS feed. That is a big sticking point. The RSS feed from OpenHAB only gives the first article. This works for say ‘Weather’, as the active article is the current weather. It does not work for news, where you may want 10 or 15 news articles all nicely formatted.

Splitting text is quite useful.

1 Like