如何用XMLStreamReader2读取元素内容为字符串(忽略内部XML/HTML)
解决Woodstox读取包含子元素的节点文本问题
好问题!我之前用Woodstox处理过类似的场景,刚好可以给你几个不需要预处理加CDATA的直接实现思路:
核心思路:手动遍历节点+跳过子元素
getElementText()确实不适用,因为它要求目标节点的子节点只能是文本/CDATA,一旦遇到嵌套元素就会抛出异常。而XMLStreamReader2提供的skipElement()方法可以帮我们高效跳过不需要的子元素,只收集文本内容。
代码示例
// 假设当前reader已经定位到<articleSummary>的START_ELEMENT reader.next(); // 移动到第一个子节点 StringBuilder summaryContent = new StringBuilder(); while (reader.getEventType() != XMLStreamConstants.END_ELEMENT) { if (reader.getEventType() == XMLStreamConstants.CHARACTERS || reader.getEventType() == XMLStreamConstants.CDATA) { // 收集文本内容 summaryContent.append(reader.getText()); } else if (reader.getEventType() == XMLStreamConstants.START_ELEMENT) { // 跳过整个子元素及其所有子节点,直接到对应的END_ELEMENT reader.skipElement(); } // 移动到下一个节点 reader.next(); }
关键说明
skipElement()是Stax2 API的扩展方法,XMLStreamReader2原生支持,它会直接将阅读器定位到当前开始元素对应的结束元素,中间的所有子节点都会被跳过,不会触发任何事件处理,效率很高。- 这种方式会收集
下所有顶层的文本节点(包括直接的文本和CDATA),完全忽略嵌套的XML/HTML标签及其内容,正好符合你的需求。
额外提示
如果你需要处理大量这类节点,可以把这段逻辑封装成一个工具方法,让代码更简洁:
public static String extractPlainText(XMLStreamReader2 reader) throws XMLStreamException { StringBuilder sb = new StringBuilder(); reader.next(); while (reader.getEventType() != XMLStreamConstants.END_ELEMENT) { if (reader.isText()) { // Stax2的isText()方法可统一判断文本/CDATA sb.append(reader.getText()); } else if (reader.isStartElement()) { reader.skipElement(); } reader.next(); } return sb.toString().trim(); }
内容的提问来源于stack exchange,提问作者zakmck
相关产品推荐
相关产品推荐

