使用Java DOM解析XML时仅重复输出最后一条条目的问题排查
问题分析
你的代码有两个关键问题导致最后一条条目被重复输出:
1. item变量被多次覆盖,仅保留最后一个节点
遍历<channel>子节点时,每次碰到<item>元素就执行item = channelListChild.item(j);,这会不断覆盖之前的item引用,最终item只指向XML里的最后一个<item>节点,前面的item根本没被处理。
2. 遍历item子节点时,非元素节点也触发打印
<item>的子节点包含空白文本节点(比如换行、缩进),你的循环不管是不是元素节点都会执行System.out.println(title)。遇到空白节点时,title已经被赋值为当前item的标题,所以会重复打印这个值。
修正后的代码
直接定位所有<item>节点遍历,避免覆盖问题,同时只在拿到有效标题后打印:
// 直接获取所有item节点,不用先遍历channel子节点 NodeList itemList = document.getElementsByTagName("item"); for (int i = 0; i < itemList.getLength(); i++) { Node item = itemList.item(i); if (item.getNodeType() == Node.ELEMENT_NODE) { NodeList childNodes = item.getChildNodes(); String title = null; for (int j = 0; j < childNodes.getLength(); j++) { Node child = childNodes.item(j); // 只处理元素节点且节点名是title的情况 if (child.getNodeType() == Node.ELEMENT_NODE && "title".equals(child.getNodeName())) { title = child.getTextContent(); break; // 找到title就停止遍历,提升效率 } } // 拿到有效标题后统一打印,避免重复输出 if (title != null) { System.out.println(title); } } } // 顺便处理channel的标题 NodeList channelList = document.getElementsByTagName("channel"); if (channelList.getLength() > 0) { Node channel = channelList.item(0); NodeList channelChild = channel.getChildNodes(); for (int i = 0; i < channelChild.getLength(); i++) { Node child = channelChild.item(i); if (child.getNodeType() == Node.ELEMENT_NODE && "title".equals(child.getNodeName())) { System.out.println(child.getTextContent()); break; } } }
额外优化建议
- 用
getElementsByTagName直接定位节点,比遍历所有子节点更高效,也更少出错。 - DOM解析会把XML里的空白(换行、缩进)当成文本节点,所以一定要判断节点类型为
ELEMENT_NODE再处理。 - 如果XML结构固定,还可以用XPath简化节点获取,比如
//item/title/text()能直接拿到所有item的标题文本。
内容的提问来源于stack exchange,提问作者Илья Величко
相关产品推荐
相关产品推荐

