Java解析XML时如何处理CDATA节点

来源:Nodejs社区作者:松本一香头衔:网络博主
导读:本期聚焦于小伙伴创作的《Java解析XML时如何处理CDATA节点》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Java解析XML时如何处理CDATA节点》有用,将其分享出去将是对创作者最好的鼓励。

Java解析XML时处理CDATA节点需要根据不同的解析方式采用对应的处理逻辑,CDATA节点内的内容会被XML解析器当作纯文本处理,不会解析其中的特殊字符,这是它和普通文本节点最大的区别。

Java解析XML时如何处理CDATA节点

什么是CDATA节点

CDATA全称是Character Data,是XML中用来存储不需要解析的文本内容的一种节点类型。当XML内容中包含大量特殊字符比如<、>、&时,使用CDATA可以避免手动转义这些字符,提升内容的可读性。CDATA节点的语法格式是<![CDATA[内容]]>,解析器会直接将中括号里的内容作为纯文本返回。

DOM解析方式处理CDATA节点

DOM解析会把整个XML文档加载到内存中形成树形结构,CDATA节点在DOM中会被识别为CDATA_SECTION_NODE类型的节点,我们可以通过节点的类型判断来获取CDATA内容。

import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.ByteArrayInputStream;

public class DomCdataParse {
    public static void main(String[] args) throws Exception {
        String xml = "<?xml version="1.0" encoding="UTF-8"?>" +
                "<root>" +
                "<content><![CDATA[<div>这是一段包含HTML标签的内容</div>]]></content>" +
                "</root>";
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(new ByteArrayInputStream(xml.getBytes()));
        // 获取content节点
        Node contentNode = document.getElementsByTagName("content").item(0);
        // 遍历content节点的子节点
        NodeList childNodes = contentNode.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node node = childNodes.item(i);
            // 判断节点类型是否为CDATA节点
            if (node.getNodeType() == Node.CDATA_SECTION_NODE) {
                System.out.println("CDATA节点内容:" + node.getNodeValue());
            } else if (node.getNodeType() == Node.TEXT_NODE) {
                // 处理普通文本节点的情况
                String text = node.getNodeValue().trim();
                if (!text.isEmpty()) {
                    System.out.println("普通文本节点内容:" + text);
                }
            }
        }
    }
}

SAX解析方式处理CDATA节点

SAX是事件驱动的解析方式,默认情况下SAX会把CDATA节点的内容拆分成多次characters方法的调用,我们需要开启CDATA处理开关,并重写startCDATAendCDATA方法来拼接完整的CDATA内容。

import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.*;
import java.io.ByteArrayInputStream;

public class SaxCdataParse {
    public static void main(String[] args) throws Exception {
        String xml = "<?xml version="1.0" encoding="UTF-8"?>" +
                "<root>" +
                "<content><![CDATA[<div>这是SAX解析的CDATA内容</div>]]></content>" +
                "</root>";
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
        parser.parse(new ByteArrayInputStream(xml.getBytes()), new CDataHandler());
    }

    static class CDataHandler extends DefaultHandler {
        private StringBuilder cdataContent = new StringBuilder();
        private boolean isInCdata = false;

        @Override
        public void startCDATA() throws SAXException {
            // 进入CDATA节点时标记状态
            isInCdata = true;
            cdataContent.setLength(0);
        }

        @Override
        public void endCDATA() throws SAXException {
            // 离开CDATA节点时输出内容
            System.out.println("SAX解析到的CDATA内容:" + cdataContent.toString());
            isInCdata = false;
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            // 如果在CDATA节点内,拼接内容
            if (isInCdata) {
                cdataContent.append(ch, start, length);
            }
        }
    }
}

StAX解析方式处理CDATA节点

StAX是拉式解析方式,开发者可以主动控制解析流程,通过判断事件类型是否为XMLStreamConstants.CDATA来获取CDATA节点的内容。

import javax.xml.stream.*;
import java.io.ByteArrayInputStream;

public class StaxCdataParse {
    public static void main(String[] args) throws Exception {
        String xml = "<?xml version="1.0" encoding="UTF-8"?>" +
                "<root>" +
                "<content><![CDATA[<div>这是StAX解析的CDATA内容</div>]]></content>" +
                "</root>";
        XMLInputFactory factory = XMLInputFactory.newInstance();
        XMLStreamReader reader = factory.createXMLStreamReader(new ByteArrayInputStream(xml.getBytes()));
        while (reader.hasNext()) {
            int event = reader.next();
            // 判断事件类型是否为CDATA
            if (event == XMLStreamConstants.CDATA) {
                System.out.println("StAX解析到的CDATA内容:" + reader.getText());
            }
        }
        reader.close();
    }
}

不同解析方式的注意事项

  • DOM解析适合XML文档较小、需要随机访问节点的场景,处理CDATA时只需要判断节点类型即可,逻辑简单但内存占用较高。
  • SAX解析适合大文件解析,内存占用低,但需要手动维护CDATA的状态标记,避免内容拼接错误。
  • StAX解析可以灵活控制解析流程,处理CDATA时直接判断事件类型即可,代码可读性较好,是现在比较推荐的中小型XML解析方式。
  • 如果XML中CDATA节点和普通文本节点混合出现,需要注意区分节点类型,避免把普通文本误当作CDATA内容处理。

常见问题解答

为什么解析后CDATA内容丢失?

最常见的原因是解析时没有开启对应的CDATA处理开关,比如SAX解析默认不会触发CDATA相关事件,需要重写startCDATAendCDATA方法。另外如果XML中CDATA节点的格式不正确,比如缺少结束的]]>,也会导致解析异常内容丢失。

CDATA节点里可以嵌套CDATA吗?

不可以,XML规范规定CDATA节点内部不能再包含CDATA的结束标记]]>,如果需要存储包含该标记的内容,只能手动将内容拆分成多个CDATA节点,或者在存储前对内容进行转义处理。

如何处理CDATA里的换行和空格?

CDATA节点内的换行和空格都会被原样保留,解析获取到的内容会包含原始的换行和空格,如果需要格式化内容,可以在获取到内容后自行处理,比如使用trim方法去除首尾空格,或者替换换行符。

JavaXML解析CDATA处理DOM解析SAX解析修改时间:2026-06-19 04:15:22

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。