Java实现嵌套XML元素价格查询:如何计算嵌套list的总价?
如何计算XML中嵌套list的总价?
你现在的核心问题是:已经能正确提取book和cd的价格存入HashMap,但嵌套list的总价始终是0,没办法递归累加它下面所有子元素(包括子list、book、cd)的价格。咱们来一步步修复这个问题:
问题根源
你的storeNodes方法只是给list设置了固定的0.0,没有去遍历它的子节点并累加所有子元素的价格——而这正是计算list总价的关键。
解决方案
咱们需要调整storeNodes方法,让它返回当前节点的总价,这样递归处理子节点时就能把价格累加起来:
1. 修改storeNodes的返回值逻辑
把storeNodes改成返回double类型,用于返回当前节点(如果是list/book/cd)的价格,非元素节点返回0。这样在处理list时,就能遍历所有子节点,把它们的返回值加起来得到list的总价。
2. 修正存储与累加逻辑
- 处理
book或cd时:提取价格存入HashMap,同时返回该价格。 - 处理
list时:初始化总价为0,遍历所有子节点,累加每个子节点的返回值,然后把总价存入HashMap,最后返回这个总价。 - 非元素节点(比如文本节点)直接返回0,不参与计算。
3. 完善getPrice方法
从HashMap中取出对应item的价格,包装成Optional<Double>返回,如果不存在就返回Optional.empty()。
修改后的完整代码
import org.w3c.dom.*; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.File; import java.util.HashMap; import java.util.Optional; public class ManageList implements Assignment7 { private HashMap<String, Double> data = new HashMap<>(); @Override public void loadXml(File input) throws Exception { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(input); doc.getDocumentElement().normalize(); // 从根节点开始递归处理 storeNodes(doc.getDocumentElement()); } @Override public Optional<Double> getPrice(String item) { // 从HashMap中获取值,不存在则返回空Optional return Optional.ofNullable(data.get(item)); } // 修改为返回当前节点的总价 public double storeNodes(Node node) { double totalPrice = 0.0; int nodeType = node.getNodeType(); if (nodeType == Node.ELEMENT_NODE) { Element element = (Element) node; String tagName = element.getTagName(); String name = element.getAttribute("name"); switch (tagName) { case "book": case "cd": // 提取价格并存储 double price = Double.parseDouble(element.getAttribute("price")); data.put(name, price); totalPrice = price; break; case "list": // 遍历所有子节点,累加总价 NodeList childNodes = node.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { totalPrice += storeNodes(childNodes.item(i)); } // 把list的总价存入HashMap data.put(name, totalPrice); break; default: // 其他元素类型,不处理,返回0 break; } } // 非元素节点(比如文本节点)返回0 return totalPrice; } }
测试效果
运行后你的HashMap会变成:{B1=30.0, B2=20.0, C1=15.0, C2=5.0, B3=10.0, L2=30.0, C3=15.0, B4=60.0, L1=125.0, root=155.0}
此时调用getPrice("L1")会返回Optional[125.0],getPrice("B1")返回Optional[30.0],完全符合你想要的效果。
内容的提问来源于stack exchange,提问作者madturtle182
相关产品推荐
相关产品推荐

