java - Java:获取嵌套xml文件中子节点值的总和
问题描述
我需要制作一个程序来输出 xml 文件中特定元素的价格。xml 文件如下所示:
<list name="root">
<book name="B1" price="30" isbn="123"/>
<list name="L1">
<book name="B2" price="20" isbn="234"/>
<list name="L2">
<cd name="C1" price="15"/>
<cd name="C2" price="5"/>
<book name="B3" price="10" isbn="345"/>
</list>
<cd name="C3" price="15"/>
<book name="B4" price="60" isbn="456"/>
</list>
</list>
我的程序应该输出如下内容:
获取价格(B1)= 30;
获取价格(L1) = B2+L2+C3+B4 = 125 ...
我的想法是将名称和值存储在哈希图中,然后从中获取值。但是,我很难获得嵌套列表的价格。该程序也应该适用于不同的 xml 文件。只有类型(cd、book 和 list)是相同的。
到目前为止,这是我的代码:
public class ManageList implements Assignment7 {
private HashMap<String, Double> data = new HashMap<String, Double>();
@Override
public void loadXml(File input) throws Exception {
// given in the readme
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
// get filename => absolute path
String filename = input.getAbsolutePath();
Document doc = db.parse(new File(filename));
// Normalize the XML Structure
doc.getDocumentElement().normalize();
// get the root element from XML document
// Element root = doc.getDocumentElement();
// ####################################
// acces elements and their attributes and store it in a hashmap
// ####################################
NodeList nl = doc.getElementsByTagName("*");
storeNodes(nl);
//System.out.println(Arrays.asList(data));
}
@Override
public Optional<Double> getPrice(String item) {
return null;
}
public void storeNodes(NodeList nl) {
for (int i = 0; i < nl.getLength(); i++) {
Node n = nl.item(i);
int type = n.getNodeType();
if (type == Node.ELEMENT_NODE) {
Element e = (Element) n;
if (e.getTagName() == "book" || e.getTagName() == "cd") {
data.put(e.getAttribute("name"), Double.parseDouble(e.getAttribute("price")));
}
if (e.getTagName() == "list" && n.hasChildNodes()) {
String name = e.getAttribute("name");
//here i get a NumberFormatException
//data.put(name, Double.parseDouble(e.getAttribute("price")));
//just to show output
data.put(name, 0.0);
}
storeNodes(n.getChildNodes());
}
}
}
哈希图输出:
[{B2=20.0, C3=15.0, B3=10.0, B4=60.0, L1=0.0, L2=0.0, root=0.0, C1=15.0, B1=30.0, C2=5.0}]
如何获取嵌套列表的值?谢谢!
解决方案
由于list
包含子属性,循环 from nList.getLength()-1
to0
将避免很多问题。
对于列表,我们需要子属性的值(价格)book
和cd
。因此,从最后一个到第一个循环将帮助我们将子属性的值存储在data
前面的步骤中。
现在,为了获得列表的总价格,我们遍历书籍和 cd 的 NodeList。我们总结了构成列表价格的所有值。
下面是代码如果(e.getTagName() == "list" && n.hasChildNodes()
,
NodeList books = e.getElementsByTagName("book");
NodeList cd = e.getElementsByTagName("cd");
System.out.println(books.getLength());
System.out.println(cd.getLength());
double listPrice = 0;
for(int i=0;i<books.getLength();i++) {
Node t = books.item(i);
Element e1 = (Element)t;
/**This can be reduced if we loop from nList.getLength()-1 to 0, Since the data already exists in data.
//if (!data.containsKey(e1.getAttribute("name"))){
// data.put(e1.getAttribute("name"),Double.parseDouble(e1.getAttribute("price")));
//
//}
*/
listPrice += Double.parseDouble(e1.getAttribute("price"));
}
for(int i=0;i<cd.getLength();i++){
Node t = cd.item(i);
Element e1 = (Element)t;
listPrice += Double.parseDouble(e1.getAttribute("price"));
}
如有任何疑问 - 评论。
谢谢。
推荐阅读
- javascript - 如何根据下拉选择和按钮单击从 MySql 数据库中检索数据?
- excel - 宏不粘贴值
- qt - 如何将代理添加到 Qt Creator
- laravel - Laravel 和 react 原生聊天
- java - S3 java v1 => v2:putObject 仅在调试时有效 - SdkClientException:无法执行 HTTP 请求:读取超时
- terraform-provider-azure - Azure 发布管道,terraform 任务 - 无法通过 Azure 进行身份验证,报告错误 700016
- java - 使用 Java 和 MyBatis 将 long as NULL 插入 PostgreSQL 中的 bigint 列
- amazon-redshift - 为什么在 Redshift 上使用窗口函数时查询计划器成本会出现跳跃?
- javascript - 在chartjs中显示具有多个标签和来自api的多个数据集的折线图
- winforms - 在安装 Windows 安装程序包之前检查是否安装了先决条件