将新元素合并到 xml 文件并按年份分组
Merging new elements to xml file and grouping them by year
我的问题是我想通过 XML 文件中的 Data
来存储我的 Expenditure
对象,但是对于每个 Expenditure
新实例 Year
元素已创建,看起来像这样:
<Expenditures xmlns="testing">
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2017">
<Expenditure>
<date>03-01-2017</date>
<money>USD 2</money>
<description>parking ticket</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2019">
<Expenditure>
<date>09-01-2019</date>
<money>PLN 1.5</money>
<description>Batonik czekoladowy</description>
<type>FOOD</type>
</Expenditure>
</year>
<year xmlns="" y="2019">
<Expenditure>
<date>09-01-2019</date>
<money>USD 1.5</money>
<description>guma balonowa</description>
<type>FOOD</type>
</Expenditure>
</year>
</Expenditures>
我的 XML 应该是这样的:
<Expenditures xmlns="testing">
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2017">
<Expenditure>
<date>03-01-2017</date>
<money>USD 2</money>
<description>parking ticket</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2019">
<Expenditure>
<date>09-01-2019</date>
<money>PLN 1.5</money>
<description>Batonik czekoladowy</description>
<type>FOOD</type>
</Expenditure>
<Expenditure>
<date>09-01-2019</date>
<money>USD 1.5</money>
<description>guma balonowa</description>
<type>FOOD</type>
</Expenditure>
</year>
</Expenditures>
这是我的代码:
public static void mergeToXMLTesting() throws Exception {
User user = User.mock();
Document doc = new Document();
doc.setRootElement(new Element("Expenditures", Namespace.getNamespace("testing")));
InputStream in = Main.class.getResourceAsStream(System.getProperty("user.dir") + "/testxml2.xml");
SAXBuilder builder = new SAXBuilder();
File xmlFile = new File(System.getProperty("user.dir") + "/testxml2.xml");
Document document = (Document) builder.build(xmlFile);
Element rootNode = document.getRootElement();
for (Expenditure e : user.getExpenditures()) {
int year = e.getDate().getYear();
String query = "//year[@y='" + year + "']";
XPathExpression<Element> xpe = XPathFactory.instance().compile(query, Filters.element());
Element thisYear = null;
if (!xpe.evaluate(document).isEmpty()) {
thisYear = xpe.evaluate(document).get(0);
System.out.println("found year " + year);
Element expenditure = new Element("Expenditure");
expenditure.addContent(new Element("date")
.setText(Utils.getFormattedDateTime("dd-MM-yyyy", new DateTime(e.getDate()))));
expenditure.addContent(new Element("money").setText(e.getMonetaryAmount().toString()));
expenditure.addContent(new Element("description").setText(e.getDescription()));
expenditure.addContent(new Element("type").setText(e.getType().name()));
thisYear.addContent(expenditure);
} else {
thisYear = new Element("year");
thisYear.setAttribute("y", year + "");
Element expenditure = new Element("Expenditure");
expenditure.addContent(new Element("date")
.setText(Utils.getFormattedDateTime("dd-MM-yyyy", new DateTime(e.getDate()))));
expenditure.addContent(new Element("money").setText(e.getMonetaryAmount().toString()));
expenditure.addContent(new Element("description").setText(e.getDescription()));
expenditure.addContent(new Element("type").setText(e.getType().name()));
thisYear.addContent(expenditure);
//doc.getRootElement().addContent(thisYear);
}
doc.getRootElement().addContent(thisYear);
}
XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
xmlOutputter.output(doc, new FileOutputStream(System.getProperty("user.dir") + "/testxml2.xml"));
}
问题是您将 thisYear
元素放在 for (Expenditure e : user.getExpenditures())
循环的每次迭代中。
我建议以其他方式重写整个逻辑:
在迭代之前按年份对支出进行分组。
Map<Integer, List<Expenditure>> groups = expenditures.stream().collect(Collectors.groupingBy(e -> e.getDate().getYear()));
for (Entry<Integer, List<Expenditure>> entry : groups.entrySet()) {
thisYear = new Element("year");
thisYear.setAttribute("y", year + "");
entry.getValues().forEach( e -> {
Element expenditure = new Element("Expenditure");
expenditure.addContent(new Element("date")
.setText(Utils.getFormattedDateTime("dd-MM-yyyy", new DateTime(e.getDate()))));
expenditure.addContent(new Element("money").setText(e.getMonetaryAmount().toString()));
expenditure.addContent(new Element("description").setText(e.getDescription()));
expenditure.addContent(new Element("type").setText(e.getType().name()));
thisYear.addContent(expenditure);
});
doc.getRootElement().addContent(thisYear);
}
抱歉,如果有任何编译错误,我没有完整的代码上下文。
我的问题是我想通过 XML 文件中的 Data
来存储我的 Expenditure
对象,但是对于每个 Expenditure
新实例 Year
元素已创建,看起来像这样:
<Expenditures xmlns="testing">
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2017">
<Expenditure>
<date>03-01-2017</date>
<money>USD 2</money>
<description>parking ticket</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2019">
<Expenditure>
<date>09-01-2019</date>
<money>PLN 1.5</money>
<description>Batonik czekoladowy</description>
<type>FOOD</type>
</Expenditure>
</year>
<year xmlns="" y="2019">
<Expenditure>
<date>09-01-2019</date>
<money>USD 1.5</money>
<description>guma balonowa</description>
<type>FOOD</type>
</Expenditure>
</year>
</Expenditures>
我的 XML 应该是这样的:
<Expenditures xmlns="testing">
<year xmlns="" y="2014">
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
<Expenditure>
<date>01-01-2014</date>
<money>EUR 1</money>
<description>bilet autobusowy</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2017">
<Expenditure>
<date>03-01-2017</date>
<money>USD 2</money>
<description>parking ticket</description>
<type>TRANSPORT</type>
</Expenditure>
</year>
<year xmlns="" y="2019">
<Expenditure>
<date>09-01-2019</date>
<money>PLN 1.5</money>
<description>Batonik czekoladowy</description>
<type>FOOD</type>
</Expenditure>
<Expenditure>
<date>09-01-2019</date>
<money>USD 1.5</money>
<description>guma balonowa</description>
<type>FOOD</type>
</Expenditure>
</year>
</Expenditures>
这是我的代码:
public static void mergeToXMLTesting() throws Exception {
User user = User.mock();
Document doc = new Document();
doc.setRootElement(new Element("Expenditures", Namespace.getNamespace("testing")));
InputStream in = Main.class.getResourceAsStream(System.getProperty("user.dir") + "/testxml2.xml");
SAXBuilder builder = new SAXBuilder();
File xmlFile = new File(System.getProperty("user.dir") + "/testxml2.xml");
Document document = (Document) builder.build(xmlFile);
Element rootNode = document.getRootElement();
for (Expenditure e : user.getExpenditures()) {
int year = e.getDate().getYear();
String query = "//year[@y='" + year + "']";
XPathExpression<Element> xpe = XPathFactory.instance().compile(query, Filters.element());
Element thisYear = null;
if (!xpe.evaluate(document).isEmpty()) {
thisYear = xpe.evaluate(document).get(0);
System.out.println("found year " + year);
Element expenditure = new Element("Expenditure");
expenditure.addContent(new Element("date")
.setText(Utils.getFormattedDateTime("dd-MM-yyyy", new DateTime(e.getDate()))));
expenditure.addContent(new Element("money").setText(e.getMonetaryAmount().toString()));
expenditure.addContent(new Element("description").setText(e.getDescription()));
expenditure.addContent(new Element("type").setText(e.getType().name()));
thisYear.addContent(expenditure);
} else {
thisYear = new Element("year");
thisYear.setAttribute("y", year + "");
Element expenditure = new Element("Expenditure");
expenditure.addContent(new Element("date")
.setText(Utils.getFormattedDateTime("dd-MM-yyyy", new DateTime(e.getDate()))));
expenditure.addContent(new Element("money").setText(e.getMonetaryAmount().toString()));
expenditure.addContent(new Element("description").setText(e.getDescription()));
expenditure.addContent(new Element("type").setText(e.getType().name()));
thisYear.addContent(expenditure);
//doc.getRootElement().addContent(thisYear);
}
doc.getRootElement().addContent(thisYear);
}
XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
xmlOutputter.output(doc, new FileOutputStream(System.getProperty("user.dir") + "/testxml2.xml"));
}
问题是您将 thisYear
元素放在 for (Expenditure e : user.getExpenditures())
循环的每次迭代中。
我建议以其他方式重写整个逻辑: 在迭代之前按年份对支出进行分组。
Map<Integer, List<Expenditure>> groups = expenditures.stream().collect(Collectors.groupingBy(e -> e.getDate().getYear()));
for (Entry<Integer, List<Expenditure>> entry : groups.entrySet()) {
thisYear = new Element("year");
thisYear.setAttribute("y", year + "");
entry.getValues().forEach( e -> {
Element expenditure = new Element("Expenditure");
expenditure.addContent(new Element("date")
.setText(Utils.getFormattedDateTime("dd-MM-yyyy", new DateTime(e.getDate()))));
expenditure.addContent(new Element("money").setText(e.getMonetaryAmount().toString()));
expenditure.addContent(new Element("description").setText(e.getDescription()));
expenditure.addContent(new Element("type").setText(e.getType().name()));
thisYear.addContent(expenditure);
});
doc.getRootElement().addContent(thisYear);
}
抱歉,如果有任何编译错误,我没有完整的代码上下文。