【问题标题】:Java: Get sum of child node values in a nested xml fileJava:获取嵌套xml文件中子节点值的总和
【发布时间】:2019-11-29 08:40:57
【问题描述】:

我需要制作一个程序来输出 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>

我的程序应该输出如下内容:

getPrice(B1) = 30;

getPrice(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}]

如何获取嵌套列表的值? 谢谢!

【问题讨论】:

    标签: java xml dom


    【解决方案1】:

    由于list 包含子属性,从nList.getLength()-1 循环到0 将避免很多问题。

    对于列表,我们需要子属性 bookcd 的值(价格)。因此,从最后一个循环到第一个循环将有助于我们将子属性的值存储在data 中作为前面的步骤。

    现在,为了获得列表的总价格,我们遍历书籍和 cd 的 NodeList。 我们总结了构成列表价格的所有值。

    下面是(e.getTagName() == "list" &amp;&amp; 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"));
    }
    

    如有任何疑问 - 发表评论。

    谢谢。

    【讨论】:

    • 非常感谢!我想这会解决我的问题。
    • 很高兴它有帮助!:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    • 1970-01-01
    • 1970-01-01
    • 2016-10-09
    • 1970-01-01
    相关资源
    最近更新 更多