Java 从xml列表中获取平均值

Java 从xml列表中获取平均值,java,xml,date,loops,Java,Xml,Date,Loops,我有一个列表使用情况\包含一些字段年份、月份和使用情况的数据列表,我想得到使用情况字段最后3个月的平均值, 我用SimpleDataFormat和getTime尝试了类似Calendar.getInstance的东西 但是因为我没有真正的约会,所以它不起作用,最好的方法是什么,请举个例子。谢谢,谢谢你 <USAGE_LIST> <TOTAL> <YEAR>2013</YEAR>

我有一个列表使用情况\包含一些字段年份、月份和使用情况的数据列表,我想得到使用情况字段最后3个月的平均值, 我用SimpleDataFormat和getTime尝试了类似Calendar.getInstance的东西 但是因为我没有真正的约会,所以它不起作用,最好的方法是什么,请举个例子。谢谢,谢谢你

<USAGE_LIST>
            <TOTAL>
            <YEAR>2013</YEAR>
            <MONTH>10</MONTH>
            <USAGE>200</USAGE>
            </TOTAL>
            <TOTAL>
            <YEAR>2013</YEAR>
            <MONTH>11</MONTH>
            <USAGE>250</USAGE>
            </TOTAL>
            <TOTAL>
            <YEAR>2013</YEAR>
            <MONTH>12</MONTH>
            <USAGE>500</USAGE>
            </TOTAL>
            <TOTAL>
            <YEAR>2014</YEAR>
            <MONTH>1</MONTH>
            <USAGE>300</USAGE>
            </TOTAL>
</USAGE_LIST>
您仍然可以仅使用年和月构造日历实例,请尝试以下操作:

Calendar Calendar=Calendar.getInstance//获取一个新的日历实例 calendar.clear;//清除它 calendar.setCalendar.MONTH,MONTH;//设定新的月份和年份 calendar.setCalendar.YEAR,YEAR; 日期=calendar.getTime//给你日期值 您可以使用日历:

Calendar c = new GregorianCalendar(year, month, dayOfMonth);

创建日历实例Calendar.getInstance和Calendar.set,并将其设置为所需的日期。您可以使用Calendar.Year和Calendar.Month作为参数进行设置


假设您已将xml文件读入字符串[],其中每一行都是数组中的一个元素。只需迭代数组,检查年份和月份,当它们是正确的集合时,再次迭代并解析出用法。重复3次并计算平均值。

我为您编写了完整的工作示例。它包含XML读取、过滤旧日期和平均使用计数。我使用xpath从XML文件中检索元素

请注意,您提供的使用列表仅包含3个月以上的日期。因此,要使其正常工作并输出0以外的内容,您需要添加/修改它以获得更近的日期

只需复制并复制这个示例,然后将usage list xml文件添加到同一个源文件夹中

package com.test;

import java.io.IOException;
import java.util.Calendar;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class AverageUsage {

    public static void main(String[] args) {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder;
        Document doc = null;
        int usageSum = 0;
        int usageCount = 0;

        // Create calendar representing now (used later)
        Calendar threeMonthsBefore = Calendar.getInstance();

        // Subtract 3 months from now
        threeMonthsBefore.add(Calendar.MONTH, -3);

        try {
            builder = factory.newDocumentBuilder();
            doc = builder.parse("src/data.xml");

            // Create XPathFactory object
            XPathFactory xpathFactory = XPathFactory.newInstance();

            // Create XPath object
            XPath xpath = xpathFactory.newXPath();

            // Create xpath expression to query our totals
            XPathExpression expr = xpath.compile("/USAGE_LIST/TOTAL");

            // Evaluate expression result on XML document
            NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);

            // Iterate over all TOTAL elements
            for(int i = 0; i < nodes.getLength(); i++){
                // Current total element
                Element total = (Element)nodes.item(i);

                // Get YEAR, MONTH, USAGE elements from current TOTAL element
                Element year = (Element)total.getElementsByTagName("YEAR").item(0);
                Element month = (Element)total.getElementsByTagName("MONTH").item(0);
                Element usage = (Element)total.getElementsByTagName("USAGE").item(0);

                // Read values as int
                int yearValue = Integer.valueOf(year.getTextContent());
                int monthValue = Integer.valueOf(month.getTextContent());
                int usageValue = Integer.valueOf(usage.getTextContent());

                // Get calendar instance & reset it
                Calendar cal = Calendar.getInstance();
                cal.set(Calendar.HOUR_OF_DAY, 0); // ! clear would not reset the hour of day !
                cal.clear(Calendar.MINUTE);
                cal.clear(Calendar.SECOND);
                cal.clear(Calendar.MILLISECOND);
                cal.clear(Calendar.DATE);

                // Set calendar date
                cal.set(Calendar.YEAR, yearValue);
                cal.set(Calendar.MONTH, monthValue);

                // Check if cal date is less than 3 months old
                if(cal.after(threeMonthsBefore)){
                    usageSum += usageValue;
                    usageCount++;
                }
            }

            if(usageCount > 0){
                float average = usageSum / (float) usageCount;
                System.out.println("Average usage in past 3 months is: " + average);

            }else{
                System.out.println("There were no usage in past 3 months.");
            }


        } catch (ParserConfigurationException | SAXException | IOException
                | XPathExpressionException e) {
            e.printStackTrace();
        }
    }

}

我不太清楚你所说的最后三个月是什么意思,但让我们假设你指的是所有元素的平均使用量,这些元素的年/月在今天日期之前的三个月内

具体取决于您希望日期算法的工作方式,在XPath2.0或XQuery 3.0中,可以表示为

avg(/USAGE_LIST/TOTAL[(current-date() - xs:date(concat(YEAR, '-', MONTH, '-01')
                        gt xs:dayTimeDuration('P90D')]) 
当然,您可以从Java调用许多XPath2.0和/或XQuery 1.0库;撒克逊人就是其中之一


上述表达式的确切含义是获得过去90天内发生月份1的所有月份的平均值。如果您想更准确地说明您的意图,我相信XPath 2.0的功能足以反映这一点。

我尝试过,但因为我得到的不是真实的日期,而是一个字符串,它不起作用。请添加您的编组代码以及如何读取xml元素,我无法找出主要问题。这是一个相当好的说明,在我看来,这就是为什么XML处理在XPath/XQuery中比在低级Java代码中做得更好的原因……在我这边做了一些代码更改之后,您的示例对我的问题很好。谢谢我很高兴这有帮助。这种类型的XML节点查询更具可移植性和可读性,特别是对于非常复杂的结构