博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Web版RSS阅读器(一)——dom4j读取xml(opml)文件
阅读量:6714 次
发布时间:2019-06-25

本文共 10828 字,大约阅读时间需要 36 分钟。

hot3.png

      接触java不久,偶有收获,最近想做一个web版RSS阅读器来锻炼一下。手头有几个从不同版本的foxmail中导出的opml文件,大家应该都知道,opml文件就是xml格式的。那么就先从这里入手,练习一下使用dom4j读取xml文件。

      在java程序设计中,尤其是java web开发程序,xml应用频率超高。Spring、Hibernate、Struts等各种web 框架,MyEclipse、Oracle等IDE,也都主要依托xml。可以说xml对于系统的配置,有着至关重要的作用。而这些也同时增强了系统的灵活性。

      先说一下思路:

      新建一个java web项目,不过暂时没有使用jsp,servlet。本文只是使用自带的调试器,先进行测试读取xml。接下来的博文中,会带大家一起显示在已经优化的界面中,并提供大部分的rss阅读器的功能。

      由于从不同版本的foxmail中导出,文件格式稍有不同,主要分歧是在订阅分组功能上。有的版本导出来的分组信息是在head/title内容中,body/outline则放的是全部的订阅信息;有的导出来的分组信息则是在body/outline中title和text属性中,而详细的订阅信息则放在body/outline/outline中。

      我想做的系统可以支持读取多个opml文件,所以需要一个rss文件列表配置文件【rss_config.xml】,对应一个实体:RssConfigBean.java,主要包含有opml文件路径信息;分组信息也需要单独出来,命名为【RssTeamBean.java】,包括title和text两个属性和一个订阅信息的列表。订阅信息肯定也是独立的,命名为【RssBean.java】,包括text、title、xmlUrl、htmlUrl、version、type六个属性。

      首先通过读取rss_config.xml,拿到所有opml文件路径,然后循环读取opml,拿到分组信息及每个分组下的所有详细订阅信息,保存到实体中,以供调用显示。

      光说不管用,直接上代码:

      ①. opml文件

【单分组foxmail6.5.opml】

六期新博客地址

【多分组foxmail7.opml】

Subscription in Foxmail
②. 在src中新建rss文件列表配置文件

【rss_config.xml】

单分组foxmail6.5
\rss\单分组foxmail6.5.opml
多分组foxmail7
\rss\多分组foxmail7.opml

③. 新建包com.tgb.rssreader.bean,添加3个java文件:

【RssBean.java】详细订阅信息

package com.tgb.rssreader.bean;/** * 详细订阅信息 * @author Longxuan * */public class RssBean {		/**	 * 显示名称	 */	private String text;		/**	 * 标题	 */	private String title;		/**	 * rss订阅地址	 */	private String htmlUrl;		/**	 * rss订阅地址	 */	private String xmlUrl;		/**	 * 版本	 */	private String version;		/**	 * 类型	 */	private String type;	public String getText() {		return text;	}	public void setText(String text) {		this.text = text;	}	public String getTitle() {		return title;	}	public void setTitle(String title) {		this.title = title;	}	public String getHtmlUrl() {		return htmlUrl;	}	public void setHtmlUrl(String htmlUrl) {		this.htmlUrl = htmlUrl;	}	public String getXmlUrl() {		return xmlUrl;	}	public void setXmlUrl(String xmlUrl) {		this.xmlUrl = xmlUrl;	}	public String getVersion() {		return version;	}	public void setVersion(String version) {		this.version = version;	}	public String getType() {		return type;	}	public void setType(String type) {		this.type = type;	}}
【RssConfigBean.java】 rss配置信息

package com.tgb.rssreader.bean;/** * rss配置信息 * @author Longxuan * */public class RssConfigBean {	/**	 * 分组名称	 */	private String name;		/**	 * 路径	 */	private String path;		public String getPath() {		return path;	}	public String getName() {		return name;	}	public void setName(String name) {		this.name = name;	}	public void setPath(String path) {		this.path = path;	}	}
【RssTeamBean.java】rss分组信息

package com.tgb.rssreader.bean;import java.util.List;/** * rss分组信息 * @author Longxuan * */public class RssTeamBean {	/**	 * 分组标题	 */	private String title;		/**	 * 分组名称	 */	private String text;		private List
rssBeanList ; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getText() { return text; } public void setText(String text) { this.text = text; } public List
getRssBeanList() { return rssBeanList; } public void setRssBeanList(List
rssBeanList) { this.rssBeanList = rssBeanList; } }
④. 新建包com.tgb.rssreader.manager,添加2个文件:

【RssConfigMgr.java】rss文件列表配置管理器

package com.tgb.rssreader.manager;import java.io.InputStream;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import com.tgb.rssreader.bean.RssConfigBean;/** * rss文件列表配置管理器 * @author Longxuan * */public class RssConfigMgr {	/**	 * 读取rss文件列表配置信息	 * @return	 */	public List
getRssConfig() { List
list = new ArrayList
(); RssConfigBean rssConfigBean = null; InputStream is = Thread.currentThread().getContextClassLoader() .getResourceAsStream("rss_config.xml"); if (is == null) { //System.out.println("找不到该文件"); //return null; throw new RuntimeException("找不到rss_config.xml文件"); } try { // 读取并解析XML文档 // SAXReader就是一个管道,用一个流的方式,把xml文件读出来 SAXReader reader = new SAXReader(); // 下面的是通过解析xml字符串的 Document doc = reader.read(is); Element rootElt = doc.getRootElement(); // 获取根节点 //System.out.println("根节点:" + rootElt.getName()); // 拿到根节点的名称 Iterator
iter = rootElt.elementIterator("rss-list"); // 获取根节点下的子节点rss-list // 遍历rss-list节点 while (iter.hasNext()) { Element recordEle = (Element) iter.next(); String name = recordEle.elementTextTrim("rss-name"); // 拿到rss-list节点下的子节点name值 //System.out.println("name:" + name); String path = recordEle.elementTextTrim("rss-path"); // 拿到rss-list节点下的子节点path值 //System.out.println("path:" + path); rssConfigBean = new RssConfigBean(); //保存到rssConfigBean中 rssConfigBean.setName(name); rssConfigBean.setPath(path); //保存到list中 list.add(rssConfigBean); } } catch (DocumentException e) { e.printStackTrace(); } return list; }}
【ReadXML.java】读取xml文件

package com.tgb.rssreader.manager;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import com.tgb.rssreader.bean.RssBean;import com.tgb.rssreader.bean.RssConfigBean;import com.tgb.rssreader.bean.RssTeamBean;/** * 读取xml文件 * @author Longxuan * */public class ReadXML {	// rss分组订阅列表	private List
rssTeamBeanList = new ArrayList
(); /** * 读取rss文件列表 */ public void ReadRss() { // rss文件列表配置信息实体 RssConfigMgr rssConfigMgr = new RssConfigMgr(); List
list = rssConfigMgr.getRssConfig(); String errText = "";// 记录错误信息 // 循环读取rss文件列表 for (RssConfigBean rssConfig : list) { // System.out.println(rssConfig.getName() + "----" + // rssConfig.getPath()); try { // 读取rss文件内容 ReadRss(System.getProperty("user.dir")+ rssConfig.getPath()); } catch (Exception e) { errText += e.getMessage(); } } } /** * 读取ompl文件 * * @param filePath */ private void ReadRss(String filePath) { File file = new File(filePath); if (!file.exists()) { // System.out.println("找不到【" + filePath + "】文件"); // return; throw new RuntimeException("找不到【" + filePath + "】文件"); } try { // 读取并解析XML文档 // SAXReader就是一个管道,用一个流的方式,把xml文件读出来 SAXReader reader = new SAXReader(); FileInputStream fis = new FileInputStream(file); // 下面的是通过解析xml字符串的 Document doc = reader.read(fis); // 获取根节点 Element rootElt = doc.getRootElement(); // 获取根节点 // System.out.println("根节点:" + rootElt.getName()); // 拿到根节点的名称 // 获取head/title节点 Element titleElt = (Element) rootElt.selectSingleNode("head/title");// 获取head节点下的子节点title // 获取分组名称 String title = titleElt.getTextTrim(); // 获取body节点 Element bodyElt = (Element) rootElt.selectSingleNode("body"); // 获取body下的第一个outline节点 Element outlineElt = (Element) bodyElt.selectSingleNode("outline"); // 判断该outlineElt节点的属性数量,>2说明是详细博客订阅信息,否则则是分组信息。 if (outlineElt.attributes().size() > 2) { // 详细博客订阅信息 // 实例化 RSS分组实体 RssTeamBean rssTeamBean = new RssTeamBean(); // 获取body节点下的outline节点 Iterator
iter = bodyElt.elementIterator("outline"); // 输出分组名称 // System.out.println("分组名称:" + title); // 记录分组名称 rssTeamBean.setTitle(title); rssTeamBean.setText(title); // 实例化订阅列表 List
rssBeanList = new ArrayList
(); // 获取详细博客订阅信息 ReadBlogsInfo(iter, rssBeanList); // 设置订阅列表到分组中 rssTeamBean.setRssBeanList(rssBeanList); // 添加分组到rss分组订阅列表 rssTeamBeanList.add(rssTeamBean); } else { // 分组信息 // 获取body节点下的outline节点 Iterator
iter = bodyElt.elementIterator("outline"); while (iter.hasNext()) { // 读取outline节点下的所有outline信息,每条信息都是一条订阅记录 Element TeamElt = (Element) iter.next(); // 实例化 RSS分组实体 RssTeamBean rssTeamBean = new RssTeamBean(); // 重新获取分组名称 title = TeamElt.attributeValue("title"); String text = TeamElt.attributeValue("text"); // System.out.println("分组title:" + title + " text:" + // text); // 记录分组名称和显示名称 rssTeamBean.setTitle(title); rssTeamBean.setText(text); // 实例化订阅列表 List
rssBeanList = new ArrayList
(); // 获取body节点下的outline节点 Iterator
iterRss = TeamElt.elementIterator("outline"); // 获取详细博客订阅信息 ReadBlogsInfo(iterRss, rssBeanList); // 设置订阅列表到分组中 rssTeamBean.setRssBeanList(rssBeanList); // 添加分组到rss分组订阅列表 rssTeamBeanList.add(rssTeamBean); } } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 读取当前组博客订阅信息 * * @param iter * 当前节点的子节点迭代器 * @param rssBeanList * 订阅列表 */ private void ReadBlogsInfo(Iterator
iter, List
rssBeanList) { // 遍历所有outline节点,每个节点都是一条订阅信息 while (iter.hasNext()) { RssBean rssBean = new RssBean(); Element outlineElt = (Element) iter.next(); String htmlUrl = outlineElt.attributeValue("htmlUrl"); // 拿到当前节点的htmlUrl属性值 String xmlUrl = outlineElt.attributeValue("xmlUrl"); // 拿到当前节点的xmlUrl属性值 String version = outlineElt.attributeValue("version"); // 拿到当前节点的version属性值 String type = outlineElt.attributeValue("type"); // 拿到当前节点的type属性值 String outlineTitle = outlineElt.attributeValue("title"); // 拿到当前节点的title属性值 String outlineText = outlineElt.attributeValue("text"); // 拿到当前节点的text属性值 // System.out.print("
"); rssBean.setHtmlUrl(htmlUrl); rssBean.setXmlUrl(xmlUrl); rssBean.setVersion(version); rssBean.setType(type); rssBean.setTitle(outlineTitle); rssBean.setText(outlineText); rssBean.setText(outlineText); // 将每条订阅信息,存放到订阅列表中 rssBeanList.add(rssBean); } } /** * 获取Rss分组订阅列表 * * @return */ public List
getRssTemBeanList() { return rssTeamBeanList; } public static void main(String[] args) { ReadXML readXML = new ReadXML(); readXML.ReadRss(); List
rssTemBeanList = readXML.getRssTemBeanList(); for (RssTeamBean rssTeamBean : rssTemBeanList) { System.out.println("【分组title:" + rssTeamBean.getTitle() + " text:"+ rssTeamBean.getText()+"】"); for (RssBean rssBean : rssTeamBean.getRssBeanList()) { System.out.print("
"); } System.out.println("-------------------------------------------------"); } }}
      由于没有使用jsp进行显示,所以要想看效果,直接右键main函数,选择“Run As”-》“1 Java Application” ,进行测试。这里给出效果图:

      已经可以完全读取了。不论是单组旧版的,还是多分组新版导出来的opml文件,都可以正常读取。接下来的博文中,会写怎么把结果读取到jsp,会使用树结构来显示。后续版本会加上添加,删除,修改,移动订阅信息及复制订阅信息到组。同时也提供导入,导出功能。这些都会出现在后续博客中。尽请期待。

版权声明:本文为博主原创文章,未经博主允许不得转载。

转载于:https://my.oschina.net/u/2260184/blog/518453

你可能感兴趣的文章
Javascript中进行遍历操作的所有方法
查看>>
JS的原型链和继承
查看>>
python中pyquery无法获取标签名的dom节点
查看>>
面试官:请手写一个webpack4.0配置
查看>>
有关getter 和 setter的使用
查看>>
JavaScript面向对象中的Function类型个人分享
查看>>
记录一次Webpack插件优化的经历
查看>>
【跃迁之路】【505天】程序员高效学习方法论探索系列(实验阶段262-2018.06.25)...
查看>>
ubuntu16.04 搭建java 环境
查看>>
关于 try 和 finally 中的 return
查看>>
JS 1-数据类型
查看>>
(Google I/O '17) Speeding Up Your Android Gradle Builds 在本地的实践
查看>>
最大似然法与似然函数
查看>>
SAPGUI里实现自定义的语法检查
查看>>
快速创建 HTML5 Canvas 电信网络拓扑图
查看>>
JS动画之定时器详解
查看>>
利用Tomcat发布基于Maven所构建的Jersey RESTful Web Service
查看>>
PHP之string之wordwrap()函数使用
查看>>
ABAP OPEN SQL里OPEN CURSOR和SELECT的比较
查看>>
【348天】我爱刷题系列107(2018.01.19)
查看>>