×
文章路径: Java

补齐HTML标签

发表于1年前(Feb 25, 2017 2:10:33 PM)  阅读 411  评论 0

分类: Java

标签: htmlparse 补齐标签 CompositeTag

在一些博客系统中,非文章阅读页面一般不会显示文章的文章内容,一般是显示文章的摘要信息,而摘要信息的生成,有些系统是由用户自行编辑,而有些系统是通过正文截取的。如果通过截取方式,我们代码一般很难将文章截取得恰到好处,主要是字面断字困难,只能设定截取多少个字符,而内容一般是富文本,即包含html标签,通过字数方式截取,可能将一些html标签从中打断,导致原来的富文本内容html标签不完整,而展现时浏览器会尝试修复,自动补齐丢失的标签,从而造成页面显示异常。

如何解决上面的问题呢,笔者一般通过两种方式解决。一个就是显示摘要时,将所有的html标签都去除显示,这样自然简单很多,但这只适用于小段文本,摘要比较短的情况,试想如果很长一段摘要,无格式显示,对阅读者肯定会造成反感。其次就是补齐html标签,它不是丢了几个标签吗,我们人为给他补上呗。

先直接上代码:

    public static void registerTags(Parser parser) {   
    	PrototypicalNodeFactory factory = new PrototypicalNodeFactory();   
    	factory.registerTag(new EmTag());
    	factory.registerTag(new CodeTag());
    	parser.setNodeFactory(factory);   
	}  
    
    /**
     * 补齐缺失的html标签,不包含html标签时直接返回
     * @param htmlStr
     * @return
     */
    public static String fixUpHTML(String htmlStr) {
    	if(htmlStr==null||"".equals(htmlStr)) {
    		return "";
    	}
    	try {
    		Parser parser = Parser.createParser(htmlStr, "UTF-8");
    		registerTags(parser);
        	NodeList nodelist = parser.extractAllNodesThatMatch(new NodeFilter() {   
				private static final long serialVersionUID = -1354302983867298283L;
				public boolean accept(Node node) {
					if (node instanceof CompositeTag) {
						return true;
					}
					return false;
				}
            });  
        	String str = "";   
            String tmp = "";   
            if(nodelist.size()==0) {
            	return htmlStr;
            }
            for (int i = 0; i < nodelist.size(); i++) {   
            	Node node = nodelist.elementAt(i);
            	if(node instanceof CompositeTag) {
            		CompositeTag testTag = (CompositeTag) node;   
    				if (testTag.getParent() == null) {
    			        tmp = testTag.toHtml();   
    				    str += tmp + "\n";
    				}
            	}
            }   
            htmlStr = str;
    	} catch(Exception e) {
    		e.printStackTrace();
    	}
    	return htmlStr;
    }

上面的代码借助了htmlparser这个jar包,htmlparser看名字就是一个html解析工具,我们常用他来抓取网页获取内容,他在抓取内容时,同浏览器一样,会尝试去修正网页的标签错误,帮我们补齐标签,我们现在正是利用了这个功能。

其中有一个类值得我们注意,就是org.htmlparser.tags.CompositeTag,这个是我们补齐标签的关键,官方给的解释是The base class for tags that have an end tag,即那些包含结束标签的标签基类。htmlparse将对所有CompositeTag的子类标签进行补齐操作,那CompositeTag到底包含哪些呢,请看下图:

上面就是htmlparse为我们提供的所有的CompositeTag实现,如果有些标签不幸不在上面的列表,像一些很少见的标签,如em,或者一些非标准的自定义的标签,如code,你也不要着急,htmlparse考虑得很周到,细心的同学可以发现上面代码中的registerTags方法就完成了这个操作,额外注册了两个标签,分别就是em和code标签,在解析前调用该方法即可。

最后贴出EmTag和CodeTag的代码,非常简单:

import org.htmlparser.tags.CompositeTag;

public class EmTag extends CompositeTag {

	/**
	 * 
	 */
	private static final long serialVersionUID = -1374057683681564722L;

	private static final String[] mIds = { "em" };

	public String[] getIds() {
		return (mIds);
	}


	public String[] getEnders() {
		return (mIds);
	}
}

import org.htmlparser.tags.CompositeTag;

public class CodeTag extends CompositeTag {

	/**
	 * 
	 */
	private static final long serialVersionUID = -1374057683681564722L;

	private static final String[] mIds = { "code" };

	public String[] getIds() {
		return (mIds);
	}


	public String[] getEnders() {
		return (mIds);
	}
}

 

发表评论