如何读取XML属性间的数据?以及如何将节点名作为参数、节点内容存入Map并解决节点值返回null问题
解决XML节点内容读取并存入Map的问题
首先,你的代码返回null的核心原因是DOM解析XML时会把换行、空格这类空白字符当成独立的文本节点,你直接取node.getChildNodes().item(0)很可能拿到的是空白文本节点,它的getNodeValue()自然是null。另外你的遍历逻辑没有正确过滤掉这些无关的空白节点,导致处理效率低还容易出错。
接下来给你两种可行的实现方案,都能把相同节点名的内容收集到Map<String, List<String>>里:
方案一:纯DOM API实现(修正你的原有逻辑)
这种方式基于你原来的代码改造,重点是过滤空白节点,正确获取文本内容:
import org.w3c.dom.*; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; public class XmlReader { public static void main(String[] args) { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new File("your-xml-file-path.xml")); doc.getDocumentElement().normalize(); // 标准化XML,合并相邻文本节点 Map<String, List<String>> nodeContentMap = new HashMap<>(); // 获取<list>下的所有子元素节点 NodeList nodeList = doc.getDocumentElement().getChildNodes(); for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); // 只处理元素节点,跳过空白文本、注释等节点 if (node.getNodeType() == Node.ELEMENT_NODE) { String nodeName = node.getNodeName(); // 正确获取元素的文本内容 String nodeValue = node.getTextContent().trim(); // 把内容存入Map nodeContentMap.computeIfAbsent(nodeName, k -> new ArrayList<>()).add(nodeValue); } } // 打印测试结果 nodeContentMap.forEach((key, value) -> System.out.println(key + " -> " + value)); } catch (Exception e) { e.printStackTrace(); } } }
关键改进点:
- 调用
doc.getDocumentElement().normalize():标准化XML结构,合并相邻的文本节点,减少空白节点干扰 - 只处理
Node.ELEMENT_NODE类型的节点:自动跳过注释、空白文本这类无关节点 - 用
node.getTextContent()获取元素的所有文本内容:比手动遍历子节点更可靠,自动忽略内部的空白节点
方案二:使用XPath简化查询
如果XML结构比较固定,用XPath可以更简洁地定位所有元素节点,代码更易读:
import org.w3c.dom.*; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; public class XmlXpathReader { public static void main(String[] args) { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new File("your-xml-file-path.xml")); XPath xpath = XPathFactory.newInstance().newXPath(); Map<String, List<String>> nodeContentMap = new HashMap<>(); // 查询<list>下的所有子元素 NodeList nodeList = (NodeList) xpath.evaluate("/list/*", doc, javax.xml.xpath.XPathConstants.NODESET); for (int i = 0; i < nodeList.getLength(); i++) { Element element = (Element) nodeList.item(i); String nodeName = element.getNodeName(); String nodeValue = element.getTextContent().trim(); nodeContentMap.computeIfAbsent(nodeName, k -> new ArrayList<>()).add(nodeValue); } // 打印结果 nodeContentMap.forEach((key, value) -> System.out.println(key + " -> " + value)); } catch (Exception e) { e.printStackTrace(); } } }
为什么这个方案更好?
- XPath表达式
/list/*直接定位到<list>下的所有子元素,不需要手动过滤空白节点 - 代码逻辑更清晰,专注于业务需求(收集节点内容),而不是DOM的底层节点处理
测试你的XML内容
用上面的代码处理你提供的XML,最终的Map会是这样的结构:
name -> [ElectricPlayer, Necromancer, Turnip King, Esquire, NeophyteBeliever, Twitch] particle_death_sentence -> [What am i doing with my life can you tell me?, You really had to kill me? I'm farming over here]
这样就完美实现了你想要的把节点名作为key,对应所有节点内容存入List的需求啦。
内容的提问来源于stack exchange,提问作者BurtGummer95
相关产品推荐
相关产品推荐

