如何用HTMLDocument获取HTML元素属性?Java解析代码为何未生效
解析HTML自定义属性的问题解决方案
咱们先来拆解你遇到的问题:用javax.swing.text.html相关API解析HTML时,没法检测到body标签的自定义属性a1/a2/a3,预期a1 exists返回true但实际是false。下面分情况给你说明:
问题出在哪?
1. 代码逻辑错误
你当前的代码里,在遍历元素时,错误地去检查子元素的属性,而不是当前body元素本身的属性。看这段代码:
if ((name instanceof HTML.Tag)) { StringBuffer text = new StringBuffer(); int count = element.getElementCount(); for (int i = 0; i < count; i++) { Element child = element.getElement(i); AttributeSet childAttributes = child.getAttributes(); // 这里检查的是child的属性,而不是当前element(比如body)的属性! System.out.println(" a1 exists : " + childAttributes.isDefined("a1")); } }
当element是body元素时,你循环遍历它的子元素(比如H1、p标签),然后检查子元素的属性,这当然找不到body的a1属性。
2. 默认解析器的限制
即使你修正了逻辑,默认的ParserDelegator使用的是HTML 3.2的DTD,它只会识别标准的HTML属性,对于自定义属性(比如a1)会直接忽略,不会将其存入AttributeSet中。
怎么解决?
方案1:修正代码逻辑(仅针对标准属性有效)
先把代码里的属性检查逻辑改对,直接检查当前元素的属性,而不是子元素:
while ((element = iterator.next()) != null) { System.out.println("Element : " + element); AttributeSet attributes = element.getAttributes(); Object name = attributes.getAttribute(StyleConstants.NameAttribute); if ((name instanceof HTML.Tag)) { // 直接检查当前元素的属性 System.out.println(" Attribute count : " + attributes.getAttributeCount()); System.out.println(" a1 exists : " + attributes.isDefined("a1")); // 原来的子元素遍历可以保留,用来处理文本内容 StringBuffer text = new StringBuffer(); int count = element.getElementCount(); for (int i = 0; i < count; i++) { Element child = element.getElement(i); int startOffset = child.getStartOffset(); int endOffset = child.getEndOffset(); int length = endOffset - startOffset; text.append(htmlDoc.getText(startOffset, length)); } } }
但注意:这个修正只能解决逻辑错误,对于自定义属性,默认解析器还是不会识别它们。
方案2:支持自定义属性(换用更灵活的解析库)
如果要让解析器识别自定义属性,最省心的方式是换用更现代的HTML解析库(比如jsoup),它对自定义属性的支持非常友好,代码也更简洁。
比如用jsoup的话,代码会非常简单:
import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; public class JsoupParserTest { public static void main(String[] args) throws Exception { Document doc = Jsoup.parse("<html> <head> Hello World </head> <body a1=\"ABC\" a2=\"3974\" a3=\"A1B2\"> <H1>Start Here</H1> <p>This is the body</p> </body> </html>"); Element body = doc.body(); System.out.println("a1 exists: " + body.hasAttr("a1")); System.out.println("a1 value: " + body.attr("a1")); System.out.println("a2 value: " + body.attr("a2")); System.out.println("a3 value: " + body.attr("a3")); } }
这段代码能轻松检测并获取所有自定义属性。
总结
- 你的原始代码存在逻辑错误,检查了错误元素的属性;
- 默认的
javax.swing.text.html解析器不支持自定义属性,因为它基于旧的HTML DTD; - 要么自定义解析器,要么换用更现代的HTML解析库来处理自定义属性。
内容的提问来源于stack exchange,提问作者Unhandled Exception
相关产品推荐
相关产品推荐

