本文目录导读:

我来帮你理解 JEditorPane、HTMLEditorKit 和相关的解析方法与验证器。
核心概念
JEditorPane
- Swing组件,用于显示和编辑多种格式的文本
- 支持HTML、RTF等格式
HTMLEditorKit
- 专门用于处理HTML内容的EditorKit
- 提供HTML解析和渲染功能
解析器验证器实现
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import javax.swing.event.*;
import java.io.*;
public class HTMLValidationExample {
public static void main(String[] args) {
JFrame frame = new JFrame("HTML Validator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// 创建JEditorPane
JEditorPane editor = new JEditorPane();
HTMLEditorKit kit = new HTMLEditorKit();
editor.setEditorKit(kit);
// 添加文档监听器
editor.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
validateHTML(editor);
}
@Override
public void removeUpdate(DocumentEvent e) {
validateHTML(editor);
}
@Override
public void changedUpdate(DocumentEvent e) {
validateHTML(editor);
}
});
frame.add(new JScrollPane(editor));
frame.setSize(600, 400);
frame.setVisible(true);
}
private static void validateHTML(JEditorPane editor) {
try {
// 获取HTML内容
String html = editor.getText();
// 使用HTML解析器验证
HTMLEditorKit.Parser parser = new HTMLEditorKit.Parser() {
@Override
public void parse(Reader r, ParserCallback cb, boolean ignoreCharSet)
throws IOException {
// 自定义解析逻辑
}
};
// 创建验证器
HTMLValidator validator = new HTMLValidator(html);
ValidationResult result = validator.validate();
if (!result.isValid()) {
System.out.println("HTML验证失败: " + result.getErrorMessage());
// 可以在这里添加UI提示
}
} catch (Exception ex) {
System.out.println("解析错误: " + ex.getMessage());
}
}
}
完整的HTML验证器类
import javax.swing.text.html.*;
import javax.swing.text.html.parser.*;
import java.io.*;
import java.util.*;
public class HTMLValidator {
private String htmlContent;
private List<String> errors;
public HTMLValidator(String htmlContent) {
this.htmlContent = htmlContent;
this.errors = new ArrayList<>();
}
public ValidationResult validate() {
try {
// 使用标准的HTML解析器
ParserDelegator parser = new ParserDelegator();
// 自定义回调
HTMLEditorKit.ParserCallback callback = new HTMLEditorKit.ParserCallback() {
@Override
public void handleText(char[] data, int pos) {
// 处理文本内容
}
@Override
public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
// 验证开始标签
validateStartTag(t, a, pos);
}
@Override
public void handleEndTag(HTML.Tag t, int pos) {
// 验证结束标签
validateEndTag(t, pos);
}
@Override
public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) {
// 验证自闭合标签
validateSimpleTag(t, a, pos);
}
@Override
public void handleError(String errorMsg, int pos) {
errors.add("位置 " + pos + ": " + errorMsg);
}
};
// 执行解析
parser.parse(new StringReader(htmlContent), callback, true);
return new ValidationResult(errors.isEmpty(), errors);
} catch (Exception e) {
return new ValidationResult(false,
Arrays.asList("解析异常: " + e.getMessage()));
}
}
private void validateStartTag(HTML.Tag tag, AttributeSet attrs, int pos) {
// 验证必需属性
if (tag == HTML.Tag.IMG) {
if (!attrs.containsAttribute(HTML.Attribute.SRC, null)) {
errors.add("位置 " + pos + ": <img> 标签缺少src属性");
}
}
if (tag == HTML.Tag.A) {
if (!attrs.containsAttribute(HTML.Attribute.HREF, null)) {
errors.add("位置 " + pos + ": <a> 标签缺少href属性");
}
}
}
private void validateEndTag(HTML.Tag tag, int pos) {
// 检查是否允许结束标签
if (tag == HTML.Tag.BR || tag == HTML.Tag.IMG) {
errors.add("位置 " + pos + ": <" + tag + "> 不应该有结束标签");
}
}
private void validateSimpleTag(HTML.Tag tag, AttributeSet attrs, int pos) {
// 验证自闭合标签的属性
if (tag == HTML.Tag.BR) {
// <br> 标签通常不需要属性
if (attrs.getAttributeCount() > 0) {
errors.add("位置 " + pos + ": <br> 标签不应该有属性");
}
}
}
// 内部类存储验证结果
public static class ValidationResult {
private final boolean valid;
private final List<String> errors;
public ValidationResult(boolean valid, List<String> errors) {
this.valid = valid;
this.errors = errors;
}
public boolean isValid() {
return valid;
}
public String getErrorMessage() {
return String.join("\n", errors);
}
public List<String> getErrors() {
return errors;
}
}
}
使用方法示例
public class Main {
public static void main(String[] args) {
// 测试HTML
String testHtml = """
<html>
<body>
<h1>测试页面</h1>
<img src="image.jpg">
<br>
<a href="http://example.com">链接</a>
<img> <!-- 缺少src属性 -->
<br></br> <!-- 错误的结束标签 -->
</body>
</html>
""";
// 创建验证器并验证
HTMLValidator validator = new HTMLValidator(testHtml);
HTMLValidator.ValidationResult result = validator.validate();
// 输出结果
if (result.isValid()) {
System.out.println("HTML验证通过!");
} else {
System.out.println("HTML验证失败:");
System.out.println(result.getErrorMessage());
}
}
}
高级验证功能
public class AdvancedHTMLValidator {
// 标签嵌套验证
private boolean validateNesting(String html) {
Stack<String> tagStack = new Stack<>();
// 使用正则表达式查找标签
Pattern pattern = Pattern.compile("<(/)?([a-zA-Z]+)[^>]*>");
Matcher matcher = pattern.matcher(html);
while (matcher.find()) {
String tag = matcher.group(2).toLowerCase();
boolean isClosing = matcher.group(1) != null;
if (isClosing) {
if (tagStack.isEmpty() || !tagStack.pop().equals(tag)) {
return false; // 标签不匹配
}
} else {
// 检查是否是自闭合标签
if (!isSelfClosingTag(tag)) {
tagStack.push(tag);
}
}
}
return tagStack.isEmpty(); // 所有标签都已关闭
}
private boolean isSelfClosingTag(String tag) {
return Arrays.asList("br", "img", "input", "hr", "meta", "link").contains(tag);
}
}
关键提示
- 性能考虑:频繁验证会影响性能,建议使用延迟验证
- 错误处理:解析大HTML文件时注意内存使用
- 编码问题:确保正确处理字符编码
- 安全性:验证用户输入的HTML防止XSS攻击
这个实现提供了基本的HTML验证功能,你可以根据具体需求进行扩展和定制。