Andrei Sebastian
Andrei Sebastian

Reputation: 67

Read an XML with multiple elements

I am working on a project that requires to read from an XML file which has both childs and subchilds , i have to print the information for each year (each month with the coresponding days).

This is my XML file :

<?xml version="1.0"?>
<Forecast>
<year name="2016">
    <currentyear>2016</currentyear>
    <month name="May">
        <currentmonth>May</currentmonth>
        <day name="Monday">
            <currentday>Monday</currentday>
            <date>22</date>
            <temperature>29</temperature>
            <weather>sunny</weather>
            <humidity>30</humidity>
        </day>
        <day name="Tuesday">
            <currentday>Tuesday</currentday>
            <date>23</date>
            <temperature>31</temperature>
            <weather>sunny</weather>
            <humidity>40</humidity>
        </day>
        <day name="Wednesday">
            <currentday>Wednesday</currentday>
            <date>24</date>
            <temperature>24</temperature>
            <weather>rainy</weather>
            <humidity>60</humidity>
        </day>
        <day name="Thursday">
            <currentday>Thursday</currentday>
            <date>25</date>
            <temperature>33</temperature>
            <weather>sunny</weather>
            <humidity>30</humidity>
        </day>

    </month>
    <month name="June">
        <currentmonth>June</currentmonth>
        <day name="Monday">
            <currentday>Monday</currentday>
            <date>13</date>
            <temperature>34</temperature>
            <weather>sunny</weather>
            <humidity>30</humidity>
        </day>
        <day name="Tuesday">
            <currentday>Tuesday</currentday>
            <date>14</date>
            <temperature>37</temperature>
            <weather>sunny</weather>
            <humidity>25</humidity>
        </day>
        <day name="Wednesday">
            <currentday>Wednesday</currentday>
            <date>15</date>
            <temperature>36</temperature>
            <weather>sunny</weather>
            <humidity>20</humidity>
        </day>
        <day name="Thursday">>  
            <currentday>Thursday</currentday>
            <date>16</date>
            <temperature>39</temperature>
            <weather>sunny</weather>
            <humidity>15</humidity>
        </day>
    </month>

</year>

and i have the following java code :

try
        {
            DocumentBuilderFactory docBuild = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docBuild.newDocumentBuilder();
            Document doc = docBuilder.parse(new File("D:\\users\\Popa Andrei\\Java Workspace\\YearForecast\\forecast.xml"));

            doc.getDocumentElement().normalize();
            System.out.println("Root element:"+doc.getDocumentElement().getNodeName());

            NodeList listYears = doc.getElementsByTagName("year");
            int totalYears = listYears.getLength();
            System.out.println("Total number of years:"+totalYears);
            NodeList listMonths = doc.getElementsByTagName("month");
            int totalMonths = listMonths.getLength();
            System.out.println("Total number of months:"+totalMonths);
            NodeList listDays = doc.getElementsByTagName("day");
            int totalDays = listDays.getLength();
            System.out.println("Total number of days:"+totalDays);


            for(int i = 0;i<listYears.getLength();i++)
            {
                Node firstYear= listYears.item(i);

                if(firstYear.getNodeType() == Node.ELEMENT_NODE)
                {
                    Element firstYearElement = (Element)firstYear;

                    System.out.println("Year:"+firstYearElement.getElementsByTagName("currentyear").item(0).getTextContent());

                    for(int j = 0;j<listMonths.getLength();j++)
                    {
                        Node firstMonth = listMonths.item(j);

                        if(firstMonth.getNodeType() == Node.ELEMENT_NODE)
                        {
                            Element firstMonthElement =(Element)firstMonth;

                            System.out.println("Month:"+firstMonthElement.getElementsByTagName("currentmonth").item(0).getTextContent()+"\n");

                                for(int k = 0 ;k<listDays.getLength();k++)
                                {
                                    Node firstDay = listDays.item(k);

                                    if(firstDay.getNodeType() == Node.ELEMENT_NODE)
                                    {
                                        Element firstDayElement = (Element)firstDay;

                                        System.out.println("Day:"+firstDayElement.getElementsByTagName("currentday").item(0).getTextContent());

                                        System.out.println("Date:"+firstDayElement.getElementsByTagName("date").item(0).getTextContent());

                                        System.out.println("Temperature:"+firstDayElement.getElementsByTagName("temperature").item(0).getTextContent()+" degrees");

                                        System.out.println("Weather:"+firstDayElement.getElementsByTagName("weather").item(0).getTextContent());

                                        System.out.println("Humidity:"+firstDayElement.getElementsByTagName("humidity").item(0).getTextContent()+"%");
                                    }
                                    System.out.println("\n");

                                }
                            }


                        }
                    }
                }


    }catch (SAXParseException err) {
    System.out.println ("** Parsing error" + ", line " 
         + err.getLineNumber () + ", uri " + err.getSystemId ());
    System.out.println(" " + err.getMessage ());

    }catch (SAXException e) {
    Exception x = e.getException ();
    ((x == null) ? e : x).printStackTrace ();

    }catch (Throwable t) {
    t.printStackTrace ();
    }
    System.exit (0);

    }

the output is this :

Root element:Forecast
Total number of years:1
Total number of months:2
Total number of days:8
Year:2016
Month:May

Day:Monday
Date:22
Temperature:29 degrees
Weather:sunny
Humidity:30%


Day:Tuesday
Date:23
Temperature:31 degrees
Weather:sunny
Humidity:40%


Day:Wednesday
Date:24
Temperature:24 degrees
Weather:rainy
Humidity:60%


Day:Thursday
Date:25
Temperature:33 degrees
Weather:sunny
Humidity:30%


Day:Monday
Date:13
Temperature:34 degrees
Weather:sunny
Humidity:30%


Day:Tuesday
Date:14
Temperature:37 degrees
Weather:sunny
Humidity:25%


Day:Wednesday
Date:15
Temperature:36 degrees
Weather:sunny
Humidity:20%


Day:Thursday
Date:16
Temperature:39 degrees
Weather:sunny
Humidity:15%


Month:June

Day:Monday
Date:22
Temperature:29 degrees
Weather:sunny
Humidity:30%


Day:Tuesday
Date:23
Temperature:31 degrees
Weather:sunny
Humidity:40%


Day:Wednesday
Date:24
Temperature:24 degrees
Weather:rainy
Humidity:60%


Day:Thursday
Date:25
Temperature:33 degrees
Weather:sunny
Humidity:30%


Day:Monday
Date:13
Temperature:34 degrees
Weather:sunny
Humidity:30%


Day:Tuesday
Date:14
Temperature:37 degrees
Weather:sunny
Humidity:25%


Day:Wednesday
Date:15
Temperature:36 degrees
Weather:sunny
Humidity:20%


Day:Thursday
Date:16
Temperature:39 degrees
Weather:sunny
Humidity:15%

The problem is my output should be this :

    Root element:Forecast
Total number of years:1
Total number of months:2
Total number of days:8
Year:2016
Month:May

Day:Monday
Date:22
Temperature:29 degrees
Weather:sunny
Humidity:30%


Day:Tuesday
Date:23
Temperature:31 degrees
Weather:sunny
Humidity:40%


Day:Wednesday
Date:24
Temperature:24 degrees
Weather:rainy
Humidity:60%


Day:Thursday
Date:25
Temperature:33 degrees
Weather:sunny
Humidity:30%

Month:June

Day:Monday
Date:13
Temperature:34 degrees
Weather:sunny
Humidity:30%


Day:Tuesday
Date:14
Temperature:37 degrees
Weather:sunny
Humidity:25%


Day:Wednesday
Date:15
Temperature:36 degrees
Weather:sunny
Humidity:20%


Day:Thursday
Date:16
Temperature:39 degrees
Weather:sunny
Humidity:15%

Can somebody help me solve this?

Upvotes: 2

Views: 3162

Answers (2)

Andrei Sebastian
Andrei Sebastian

Reputation: 67

Here is the correct code,thank you @RamachandranGA

    try
    {
    DocumentBuilderFactory docBuild = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = docBuild.newDocumentBuilder();
    Document doc = docBuilder.parse(new File("D:\\users\\Popa Andrei\\Java Workspace\\YearForecast\\forecast.xml"));
    NodeList monthNodes = doc.getElementsByTagName("month");
    // monthNodes.

    XPath xPath = XPathFactory.newInstance().newXPath();

    for (int i = 0; i < monthNodes.getLength(); i++) {
        StringBuilder pathBuilder = new StringBuilder();
        pathBuilder.append("/Forecast/year/month[@name=");
        pathBuilder.append("'");
        Element monthNode = (Element) monthNodes.item(i);
        String month = monthNode.getAttribute("name");
        pathBuilder.append(month);
        pathBuilder.append("']/day");

        NodeList monthWiseNodes = (NodeList) xPath.evaluate(pathBuilder.toString(), doc.getDocumentElement(),
                XPathConstants.NODESET);


        System.out.println(month+":\n");

        for(int j = 0 ;j<monthWiseNodes.getLength();j++)
        {
            Node firstDay = monthWiseNodes.item(j);

            if(firstDay.getNodeType() == Node.ELEMENT_NODE)
            {
                Element firstDayElement = (Element)firstDay;

                System.out.println("\tDay:"+firstDayElement.getElementsByTagName("currentday").item(0).getTextContent());

                System.out.println("\tDate:"+firstDayElement.getElementsByTagName("date").item(0).getTextContent());

                System.out.println("\tTemperature:"+firstDayElement.getElementsByTagName("temperature").item(0).getTextContent()+" degrees");

                System.out.println("\tWeather:"+firstDayElement.getElementsByTagName("weather").item(0).getTextContent());

                System.out.println("\tHumidity:"+firstDayElement.getElementsByTagName("humidity").item(0).getTextContent()+"%\n");
            }
        }
    }

}catch (SAXParseException err) {
    System.out.println ("** Parsing error" + ", line " 
         + err.getLineNumber () + ", uri " + err.getSystemId ());
    System.out.println(" " + err.getMessage ());

    }catch (SAXException e) {
    Exception x = e.getException ();
    ((x == null) ? e : x).printStackTrace ();

    }catch (Throwable t) {
    t.printStackTrace ();
    }
}

Upvotes: 0

Ramachandran.A.G
Ramachandran.A.G

Reputation: 4948

A really rough cut approach here. For years that change, you will have to implement it (right now I have aggregated by month only. You will have to aggregate for a key of year and month).

DocumentBuilderFactory docBuild = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docBuild.newDocumentBuilder();
        Document doc = docBuilder.parse(new File("C:\\DevelopmentTools\\3.CODE\\Weather.xml"));
        NodeList monthNodes = doc.getElementsByTagName("month");
        // monthNodes.

        XPath xPath = XPathFactory.newInstance().newXPath();

        for (int i = 0; i < monthNodes.getLength(); i++) {
            StringBuilder pathBuilder = new StringBuilder();
            pathBuilder.append("/Forecast/year/month[@name=");
            pathBuilder.append("'");
            Element monthNode = (Element) monthNodes.item(i);
            String month = monthNode.getAttribute("name");
            pathBuilder.append(month);
            pathBuilder.append("']/day");

            NodeList monthWiseNodes = (NodeList) xPath.evaluate(pathBuilder.toString(), doc.getDocumentElement(),
                    XPathConstants.NODESET);

            System.out.println("For the month of  " + month + " number of days is " + monthWiseNodes.getLength());

        }

I get this output :

For the month of May number of days is 4

For the month of June number of days is 4

Upvotes: 2

Related Questions