如何使用ParserDelegator忽略HTML/XML文件head部分仅提取body内容
实现方案
你只需要给ParserCallback新增一个是否处于body区间的状态标记,调整文本收集的触发条件即可,修改后的完整代码如下:
import javax.swing.text.MutableAttributeSet; import javax.swing.text.html.HTML; import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.parser.ParserDelegator; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.List; public class BodyHtml { public static List<String> extractText(Reader reader) throws IOException { final ArrayList<String> list = new ArrayList<>(); ParserDelegator parserDelegator = new ParserDelegator(); HTMLEditorKit.ParserCallback parserCallback = new HTMLEditorKit.ParserCallback() { // 新增状态标记:当前是否在body标签内 private boolean isInBody = false; @Override public void handleText(final char[] data, final int pos) { // 仅当处于body范围内时才收集文本 if (isInBody) { list.add(new String(data)); } } @Override public void handleStartTag(HTML.Tag tag, MutableAttributeSet attribute, int pos) { // 遇到body起始标签,标记状态为true if (tag == HTML.Tag.BODY) { isInBody = true; } } @Override public void handleEndTag(HTML.Tag t, final int pos) { // 遇到body结束标签,标记状态为false if (t == HTML.Tag.BODY) { isInBody = false; } } @Override public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, final int pos) { } @Override public void handleComment(final char[] data, final int pos) { } @Override public void handleError(final java.lang.String errMsg, final int pos) { } }; parserDelegator.parse(reader, parserCallback, true); return list; } public final static void main(String[] args) throws Exception{ FileReader reader = new FileReader("test.xhtml"); List<String> lines = BodyHtml.extractText(reader); for (String line : lines) { if(line != null && !line.trim().isEmpty()) { System.out.println(line.trim()); } } } }
逻辑说明
- 新增的
isInBody变量会在解析到<body>开头时激活,解析到</body>结尾时关闭 - 只有激活状态下的文本内容会被收集,自动忽略head、script、style等body外所有标签的内容
- ParserDelegator本身兼容HTML/XHTML的标签大小写识别,不需要额外处理标签大小写问题
内容的提问来源于stack exchange,提问作者archita
相关产品推荐
相关产品推荐

