Java解析XML时CDATA内容被当普通文本处理,需用DOM/SAX/StAX解析器正确获取原始字符串:DOM中用CDATASECTIONNODE判断并调用getTextContent();SAX中characters()回调接收CDATA数据;StAX通过CDATA事件类型和getText()提取。

Java解析XML时,CDATA节点的内容会被当作普通文本处理,不会被XML解析器解析为标签或实体。关键在于使用支持CDATA的解析器(如DOM、SAX或StAX),并正确获取其原始文本内容。
DOM解析中读取CDATA内容
在DOM中,CDATASection 是 Text 节点的子类型。只要不调用 normalize() 合并相邻文本节点,CDATA内容就能原样保留。
- 用
Node.getNodeType() == Node.CDATA_SECTION_NODE判断是否为CDATA节点 - 调用
getTextContent()或getNodeValue()可直接获取其中的原始字符串(不含和]]>标记) - 注意:如果父元素下有多个文本/CDATA节点,需遍历所有子节点并拼接,不能只依赖
Element.getTextContent()(它会合并所有文本内容,但无法区分来源)
SAX解析中捕获CDATA数据
SAX本身不显式暴露CDATA节点,但通过 DefaultHandler 的回调方法可识别:
- 重写
startCDATA()和endCDATA()方法(需使用支持该特性的解析器,如Xerces;标准JDK SAXParser默认不触发这两个方法) - 更通用的做法是重写
characters(char[], int, int)—— CDATA内容会在此方法中被传递,与普通文本无异;需结合上下文(如当前元素名)判断是否应视为CDATA - 若需严格区分,建议改用DOM或StAX
StAX解析中明确处理CDATA
StAX(Streaming API for XML)对CDATA支持最清晰:
立即学习“Java免费学习笔记(深入)”;
- 当读取到
XMLStreamReader的事件类型为 XMLStreamConstants.CDATA 时,说明遇到了CDATA节 - 调用
reader.getText()即可获取其中的纯文本内容 - 示例:
if (event == XMLStreamConstants.CDATA) { String cdata = reader.getText(); }
注意事项与常见陷阱
处理CDATA容易忽略几个细节:
- DTD或XSD校验不影响CDATA内容解析,但若XML声明了内部DTD且包含未转义的
]]>,会导致解析失败 - 某些轻量级解析器(如Android内置的PULL解析器)不支持CDATA事件,会将其作为普通字符事件处理
- 序列化回XML时,若想把一段文本写成CDATA,需手动构造
,标准DOM或StAX输出器默认不会自动包裹










