Java读取XML时无法获取嵌套CDATA内的Item节点问题求助
问题根源
CDATA块是XML里用来存储「纯文本」的容器,解析器碰到<![CDATA[...]]>时,会把里面的所有内容当成普通字符串处理,不会将其解析为结构化的XML节点。你要操作的<Item>节点本质是CDATA文本里的一串字符,并非DOM树中的真实元素节点,所以调用getElementsByTagName("Item")自然会得到空的NodeList。
解决思路&代码示例
1. 提取CDATA块内的文本内容
先定位到包含CDATA的<Expr>节点,再遍历其子节点找到CDATA类型节点,提取内部文本:
Document doc = ...; // 已加载的SOAP XML文档对象 Node exprNode = doc.getElementsByTagName("Expr").item(0); String cdataText = ""; // 遍历Expr的子节点,筛选出CDATA节点 for (int i = 0; i < exprNode.getChildNodes().getLength(); i++) { Node child = exprNode.getChildNodes().item(i); if (child.getNodeType() == Node.CDATA_SECTION_NODE) { cdataText = child.getNodeValue(); break; } }
2. 将CDATA文本解析为独立XML文档
把提取到的CDATA文本当作新的XML内容,重新解析成DOM对象,这样<Item>就会被识别为真实的XML元素:
// 初始化XML解析器 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); // 将字符串转为输入流用于解析 InputSource input = new InputSource(new StringReader(cdataText)); Document cdataDoc = builder.parse(input); // 现在可以正常获取并操作Item节点 NodeList itemNodes = cdataDoc.getElementsByTagName("Item"); for (int i = 0; i < itemNodes.getLength(); i++) { Element itemElem = (Element) itemNodes.item(i); // 执行属性赋值或删除操作 itemElem.setAttribute("newAttr", "processed"); itemElem.removeAttribute("tempAttr"); }
3. (可选)将修改后的内容写回原SOAP XML
如果需要更新原文档中的CDATA内容,把修改后的新XML转回字符串,替换原CDATA节点即可:
// 将修改后的cdataDoc转换为字符串 TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); StringWriter sw = new StringWriter(); transformer.transform(new DOMSource(cdataDoc), new StreamResult(sw)); String updatedCdata = sw.toString(); // 替换原CDATA节点 CDATASection newCdataBlock = doc.createCDATASection(updatedCdata); exprNode.replaceChild(newCdataBlock, child); // child为之前找到的原CDATA节点
注意事项
- 确保CDATA内的文本是格式合法的XML,否则解析时会抛出异常;如果文本中包含
<?xml version="1.0"?>这类XML声明,建议先删除再解析。
内容的提问来源于stack exchange,提问作者BRUNO
相关产品推荐
相关产品推荐

