JEditorPaneHTMLEditorKitParserBoolean布尔处理

wen java案例 2

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

JEditorPaneHTMLEditorKitParserBoolean布尔处理

常见场景与解决方案

HTML 属性解析为 Boolean

当解析 HTML 中的布尔属性(如 checkeddisabledreadonly)时:

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;
    }
}
  1. Swing 的 HTMLEditorKit 对布尔属性支持有限,需要手动处理
  2. 布尔属性值可能是nullStringBoolean 对象
  3. 建议创建工具类统一处理布尔属性的转换和验证
  4. 自定义 Parser 可以提供更精确的控制
  5. 总是进行 null 检查,因为解析器可能返回 null

这些代码示例应该能帮你处理 JEditorPane 中的布尔属性解析问题,如果你有具体的错误信息或使用场景,请补充说明,我可以提供更精确的解决方案。

抱歉,评论功能暂时关闭!