对于 JEditorPane 结合 HTMLEditorKit 进行 HTML 解析时遇到的 Boolean/布尔处理问题,我来帮你分析可能的场景和解决方案。

常见场景与解决方案
HTML 属性解析为 Boolean
当解析 HTML 中的布尔属性(如 checked、disabled、readonly)时:
import javax.swing.text.html.*;
import javax.swing.text.*;
import javax.swing.*;
public class BooleanHtmlParser {
public static void main(String[] args) {
JEditorPane editorPane = new JEditorPane();
editorPane.setContentType("text/html");
// 解析带布尔属性的 HTML
String html = "<html><body>" +
"<input type='checkbox' checked>" +
"<input type='text' disabled>" +
"</body></html>";
editorPane.setText(html);
// 获取 HTML 文档并解析属性
HTMLDocument doc = (HTMLDocument) editorPane.getDocument();
Element root = doc.getDefaultRootElement();
// 遍历元素
traverseElements(root);
}
private static void traverseElements(Element element) {
AttributeSet attrs = element.getAttributes();
// 检查布尔属性
Object checkedAttr = attrs.getAttribute(HTML.Attribute.CHECKED);
Object disabledAttr = attrs.getAttribute(HTML.Attribute.DISABLED);
// 布尔属性处理
if (checkedAttr != null) {
System.out.println("Found checked attribute: " + checkedAttr);
// HTMLEditorKit 中布尔属性值可能是 null 或字符串
boolean isChecked = (checkedAttr == null ||
"true".equals(checkedAttr.toString()) ||
checkedAttr.equals(Boolean.TRUE));
}
// 递归处理子元素
for (int i = 0; i < element.getElementCount(); i++) {
traverseElements(element.getElement(i));
}
}
}
自定义 Boolean 解析器
创建自定义的 TagParser 来处理布尔属性:
import javax.swing.text.html.parser.*;
import java.util.*;
public class CustomBooleanParser extends DocumentParser {
public static class BooleanAwareParser extends HTMLEditorKit.ParserCallback {
private Map<String, Boolean> booleanAttributes = new HashMap<>();
@Override
public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
// 处理布尔属性
for (HTML.Attribute attr : getBooleanAttributes()) {
Object value = a.getAttribute(attr);
if (value != null) {
boolean isBoolean = value.equals(Boolean.TRUE) ||
value.equals("") ||
value.equals(attr.toString());
if (isBoolean) {
booleanAttributes.put(attr.toString(), true);
// 转换为标准的 true/false
a.addAttribute(attr, Boolean.TRUE);
}
}
}
}
private List<HTML.Attribute> getBooleanAttributes() {
return Arrays.asList(
HTML.Attribute.CHECKED,
HTML.Attribute.DISABLED,
HTML.Attribute.READONLY,
HTML.Attribute.SELECTED,
HTML.Attribute.NOSHADE,
HTML.Attribute.NOWRAP,
HTML.Attribute.ISMAP
);
}
public Map<String, Boolean> getBooleanAttributesMap() {
return booleanAttributes;
}
}
public static void main(String[] args) {
String html = "<html><body>" +
"<input type='checkbox' checked>" +
"<input type='text' disabled readonly>" +
"<select><option selected>Option 1</option></select>" +
"</body></html>";
// 使用自定义解析器
HTMLEditorKit kit = new HTMLEditorKit();
JEditorPane editor = new JEditorPane();
editor.setEditorKit(kit);
BooleanAwareParser parser = new BooleanAwareParser();
try {
// 手动解析 HTML
javax.swing.text.html.parser.ParserDelegator delegator =
new javax.swing.text.html.parser.ParserDelegator();
delegator.parse(new java.io.StringReader(html), parser, true);
// 获取解析结果
Map<String, Boolean> booleanAttrs = parser.getBooleanAttributesMap();
System.out.println("Boolean attributes found: " + booleanAttrs);
} catch (Exception e) {
e.printStackTrace();
}
}
}
处理 Boolean 值的实用工具类
import javax.swing.text.html.*;
import javax.swing.text.*;
public class BooleanAttributeUtils {
/**
* 安全获取布尔属性值
*/
public static boolean getBooleanAttribute(AttributeSet attrs, HTML.Attribute attr) {
Object value = attrs.getAttribute(attr);
// 处理各种可能的 Boolean 表示形式
if (value == null) {
return false;
}
if (value instanceof Boolean) {
return (Boolean) value;
}
// 处理字符串表示
String strVal = value.toString();
return "true".equalsIgnoreCase(strVal) ||
"checked".equalsIgnoreCase(strVal) ||
"selected".equalsIgnoreCase(strVal) ||
"disabled".equalsIgnoreCase(strVal) ||
"readonly".equalsIgnoreCase(strVal);
}
/**
* 在 HTML 文档中查找特定布尔属性
*/
public static List<Element> findElementsWithBooleanAttribute(
HTMLDocument doc, HTML.Attribute attr) {
List<Element> result = new ArrayList<>();
Element root = doc.getDefaultRootElement();
findElementsRecursive(root, attr, result);
return result;
}
private static void findElementsRecursive(
Element element, HTML.Attribute attr, List<Element> result) {
AttributeSet attrs = element.getAttributes();
if (attrs.getAttribute(attr) != null) {
result.add(element);
}
for (int i = 0; i < element.getElementCount(); i++) {
findElementsRecursive(element.getElement(i), attr, result);
}
}
/**
* 示例:使用工具类
*/
public static void main(String[] args) {
JEditorPane editor = new JEditorPane();
editor.setContentType("text/html");
editor.setText("<html><body>" +
"<input type='checkbox' id='c1' checked>" +
"<input type='radio' id='r1' checked>" +
"</body></html>");
HTMLDocument doc = (HTMLDocument) editor.getDocument();
// 查找所有包含 checked 属性的元素
List<Element> checkedElements =
findElementsWithBooleanAttribute(doc, HTML.Attribute.CHECKED);
for (Element elem : checkedElements) {
boolean isChecked = getBooleanAttribute(
elem.getAttributes(), HTML.Attribute.CHECKED);
System.out.println("Element: " + elem.getName() +
" checked: " + isChecked);
}
}
}
自定义 HTMLEditorKit 扩展
import javax.swing.text.html.*;
import javax.swing.text.*;
public class EnhancedHTMLEditorKit extends HTMLEditorKit {
@Override
public Document createDefaultDocument() {
HTMLDocument doc = new HTMLDocument() {
@Override
public HTMLEditorKit.ParserCallback getReader(int pos) {
return new HTMLDocument.HTMLReader(pos) {
@Override
public void handleSimpleTag(HTML.Tag t,
MutableAttributeSet a, int pos) {
// 处理自闭合标签的布尔属性
processBooleanAttributes(t, a);
super.handleSimpleTag(t, a, pos);
}
@Override
public void handleStartTag(HTML.Tag t,
MutableAttributeSet a, int pos) {
// 处理开始标签的布尔属性
processBooleanAttributes(t, a);
super.handleStartTag(t, a, pos);
}
private void processBooleanAttributes(HTML.Tag t,
MutableAttributeSet a) {
// 枚举所有属性
Enumeration<?> names = a.getAttributeNames();
while (names.hasMoreElements()) {
Object name = names.nextElement();
if (name instanceof HTML.Attribute) {
HTML.Attribute attr = (HTML.Attribute) name;
Object value = a.getAttribute(attr);
// 转换布尔值
if (value != null && !(value instanceof Boolean)) {
String strVal = value.toString();
if ("".equals(strVal) ||
attr.toString().equals(strVal)) {
a.addAttribute(attr, Boolean.TRUE);
}
}
}
}
}
};
}
};
return doc;
}
}
使用示例
public class Main {
public static void main(String[] args) {
// 使用增强的 EditorKit
JEditorPane editor = new JEditorPane();
editor.setEditorKit(new EnhancedHTMLEditorKit());
// 解析带布尔属性的 HTML
String html = "<html><body>" +
"<form>" +
"<input type='checkbox' checked='checked'> Checked" +
"<input type='checkbox'> Unchecked" +
"<input type='text' disabled='disabled'>" +
"<select><option selected='selected'>Selected</option></select>" +
"</form></body></html>";
editor.setText(html);
// 验证解析结果
HTMLDocument doc = (HTMLDocument) editor.getDocument();
// 使用工具类获取属性
boolean checkBox1Checked = BooleanAttributeUtils.getBooleanAttribute(
getFirstInputElement(doc), HTML.Attribute.CHECKED);
System.out.println("Checkbox checked: " + checkBox1Checked);
}
private static AttributeSet getFirstInputElement(HTMLDocument doc) {
Element root = doc.getDefaultRootElement();
return findElementByTag(root, HTML.Tag.INPUT);
}
private static AttributeSet findElementByTag(Element element, HTML.Tag tag) {
AttributeSet attrs = element.getAttributes();
Object name = attrs.getAttribute(
javax.swing.text.StyleConstants.NameAttribute);
if (tag.equals(name)) {
return attrs;
}
for (int i = 0; i < element.getElementCount(); i++) {
AttributeSet found = findElementByTag(element.getElement(i), tag);
if (found != null) return found;
}
return null;
}
}
- Swing 的 HTMLEditorKit 对布尔属性支持有限,需要手动处理
- 布尔属性值可能是:
null、String、Boolean对象 - 建议创建工具类统一处理布尔属性的转换和验证
- 自定义 Parser 可以提供更精确的控制
- 总是进行 null 检查,因为解析器可能返回 null
这些代码示例应该能帮你处理 JEditorPane 中的布尔属性解析问题,如果你有具体的错误信息或使用场景,请补充说明,我可以提供更精确的解决方案。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播