Informaを使ってRSSを処理してみる。
RSS等を処理するライブラリ「Informa」を使って、RSSを解析してみる。
解析するRSSは、ライブドアのWeather Hacksとし、RSSフィード一覧から全国の地点定義表を取得し、それから全国142箇所の天気予報を取得する。
なお、地点定義表の解析は普通のDOMで解析した。
import java.awt.BorderLayout; import java.awt.Component; import java.awt.Image; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.imageio.ImageIO; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import de.nava.informa.core.ChannelIF; import de.nava.informa.core.ItemIF; import de.nava.informa.core.ParseException; import de.nava.informa.impl.basic.ChannelBuilder; import de.nava.informa.parsers.FeedParser; public class RssPanel extends JPanel{ private static final long serialVersionUID = 1L; private DefaultTableModel model; private Map<String,ImageIcon> icons; public RssPanel(){ super(new BorderLayout()); JTable table=new JTable(); super.add(new JScrollPane(table),BorderLayout.CENTER); model=new DefaultTableModel(){ private static final long serialVersionUID = 1L; @Override public boolean isCellEditable(int row, int column) { return false; } }; model.setRowCount(0); model.setColumnCount(3); model.setColumnIdentifiers(new String[]{"都市名","予報","URL"}); table.setModel(model); table.setRowHeight(34); table.getColumnModel().getColumn(0).setMaxWidth(80); table.getColumnModel().getColumn(1).setMaxWidth(70); table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer(){ private static final long serialVersionUID = 1L; @Override public Component getTableCellRendererComponent( JTable arg0, Object arg1, boolean arg2, boolean arg3, int arg4, int arg5) { if(arg1 instanceof ImageIcon){ JLabel ll=new JLabel((ImageIcon)arg1); return ll; }else if(arg1 instanceof URL){ return super.getTableCellRendererComponent( arg0, arg1, arg2, arg3, arg4, arg5); }else{ return super.getTableCellRendererComponent( arg0, arg1, arg2, arg3, arg4, arg5); } } }); icons=new HashMap<String,ImageIcon>(); Runnable r=new Runnable(){ public void run(){ List<Entry> urls=updateAreaCity(); model.setRowCount(urls.size()); updateModel(urls); } }; new Thread(r).start(); } private List<Entry> updateAreaCity(){ try{ List<Entry> ret=new ArrayList<Entry>(); DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance(); DocumentBuilder db=dbf.newDocumentBuilder(); URL url = new URL("http://weather.livedoor.com/forecast/rss/forecastmap.xml"); Document doc=db.parse(url.openStream()); NodeList list=doc.getChildNodes(); Node n=list.item(0); parse(n,ret); return ret; }catch(Exception e){ e.printStackTrace(); return null; } } private void parse(Node n,List<Entry> ret){ NodeList list=n.getChildNodes(); for(int i=0;i<list.getLength();i++){ Node tmp=list.item(i); if(tmp.getNodeType()==3)continue; if(tmp.getNodeName().equals("city")){ NamedNodeMap map=tmp.getAttributes(); Entry e=new Entry(); e.id=Integer.parseInt(map.getNamedItem("id").getNodeValue()); e.name=map.getNamedItem("title").getNodeValue(); e.url=map.getNamedItem("source").getNodeValue(); ret.add(e); } if(tmp.hasChildNodes()){ parse(tmp,ret); } } } private void updateModel(List<Entry> urls){ for(Entry et : urls){ try{ URL url=new URL(et.url); ChannelIF channel = FeedParser.parse(new ChannelBuilder(), url); process(channel,et); }catch(MalformedURLException e){ e.printStackTrace(); }catch (ParseException e){ e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); } } } private void process(ChannelIF channel,Entry e) throws ParseException,IOException{ Set<ItemIF> list=channel.getItems(); for(ItemIF item : list){ if(item.getTitle().contains("PR"))continue; URL url=item.getLink(); String is=item.getElementValues("image", new String[]{"url"})[0]; ImageIcon icon=icons.get(is); if(icon==null){ URL u=new URL(is); Image im=ImageIO.read(u); icon=new ImageIcon(im); } model.setValueAt(e.name, e.id-1, 0); model.setValueAt(icon, e.id-1, 1); model.setValueAt(url, e.id-1, 2); break; } } private class Entry{ int id; String name; String url; } public static void main(String[] args) { JFrame f=new JFrame(); try { UIManager.setLookAndFeel( "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); SwingUtilities.updateComponentTreeUI(f); }catch(Exception e){} f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.getContentPane().setLayout(new BorderLayout()); f.setSize(480, 320); f.getContentPane().add(new RssPanel(),BorderLayout.CENTER); f.setVisible(true); } }