Java XML解析:遍历重复节点提取子节点时的问题排查
问题描述
我用Java处理包含重复同名节点的XML文件,需要依次遍历每个<Calculation_Results>节点,提取其下的<Calculation_Result>子节点数据并插入数据库行。但目前遇到问题:每次循环都会提取所有<Calculation_Result>节点,而非当前父节点<Calculation_Results>下的子节点。
当前代码
File inputFile = new File("TestSet01_Network.xml"); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(inputFile); doc.getDocumentElement().normalize(); NodeList calcResults = doc.getElementsByTagName("Calculation_Results"); for (int a=0;a<calcResults.getLength();a++) { NodeList calcChildNodes = calcResults.getElementsByTagName("Calculation_Result"); for (int b=0;b<calcResults.getLength();b++) { String name = calcChildNodes.item(b).getAttributes().getNamedItem("Name").getTextContent(); String value = calcChildNodes.item(b).getAttributes().getNamedItem("Value").getTextContent(); // Insert rows into database } }
XML示例
<Calculation_Results Mass="1234"> <Calculation_Result Name="Name1" Value="Value1"/> <Calculation_Result Name="Name2" Value="Value2"/> <Calculation_Result Name="Name3" Value="Value3"/> </Calculation_Results> <Calculation_Results Mass="5678"> <Calculation_Result Name="Name1" Value="Value10"/> <Calculation_Result Name="Name2" Value="Value20"/> <Calculation_Result Name="Name3" Value="Value30"/> </Calculation_Results> <Calculation_Results Mass="9876"> <Calculation_Result Name="Name1" Value="Value100"/> <Calculation_Result Name="Name2" Value="Value200"/> <Calculation_Result Name="Name3" Value="Value300"/> </Calculation_Results>
解决方案
问题出在两个关键细节上:
- 你调用的
calcResults.getElementsByTagName("Calculation_Result")是从整个文档范围查找节点,而非当前<Calculation_Results>节点的子节点。 - 内层循环的终止条件错误,用了父节点列表的长度
calcResults.getLength(),而非当前父节点下子节点列表的长度。
修正后的代码如下:
File inputFile = new File("TestSet01_Network.xml"); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(inputFile); doc.getDocumentElement().normalize(); NodeList calcResults = doc.getElementsByTagName("Calculation_Results"); for (int a = 0; a < calcResults.getLength(); a++) { // 获取当前循环到的Calculation_Results父节点 Node currentParent = calcResults.item(a); // 从当前父节点出发,仅查找其下的Calculation_Result子节点 NodeList calcChildNodes = ((Element) currentParent).getElementsByTagName("Calculation_Result"); // 遍历当前父节点下的所有子节点 for (int b = 0; b < calcChildNodes.getLength(); b++) { Node childNode = calcChildNodes.item(b); String name = childNode.getAttributes().getNamedItem("Name").getTextContent(); String value = childNode.getAttributes().getNamedItem("Value").getTextContent(); // 执行数据库插入操作 // insert into ... values (?, ?) } }
核心改动说明:
- 先获取当前循环到的
<Calculation_Results>节点,将查找范围限定在该节点内部。 - 内层循环使用子节点列表的长度作为终止条件,确保只遍历当前父节点下的子节点。
内容的提问来源于stack exchange,提问作者Edmo1001
相关产品推荐
相关产品推荐

