如何用Groovy脚本按起止日期拆分Payload并生成每日数据?
Groovy实现XML按日期区间拆分节点
需求说明
需要将输入XML中的每个<results>节点,按照其StartDate到EndDate之间的每一天复制生成新的<results>节点:
- 保留原节点的
loc、loc_name、points字段 - 移除原节点的
StartDate和EndDate,新增<Date>字段,日期为区间内的每一天,时间部分沿用原StartDate的时分秒
输入Payload
<root> <results> <loc>Loc 10</loc> <loc_name>Loc Desc10</loc_name> <points>3</points> <StartDate>2023-09-11T22:39:40Z</StartDate> <EndDate>2023-09-13T22:45:36.437000Z</EndDate> </results> <results> <loc>Loc 11</loc> <loc_name>Loc Desc 11</loc_name> <points>4</points> <StartDate>2023-09-16T22:39:40Z</StartDate> <EndDate>2023-09-18T22:45:36.437000Z</EndDate> </results> </root>
期望输出Payload
<root> <results> <loc>Loc 10</loc> <loc_name>Loc Desc10</loc_name> <points>3</points> <Date>2023-09-11T22:39:40Z</Date> </results> <results> <loc>Loc 10</loc> <loc_name>Loc Desc10</loc_name> <points>3</points> <Date>2023-09-12T22:39:40Z</Date> </results> <results> <loc>Loc 10</loc> <loc_name>Loc Desc10</loc_name> <points>3</points> <Date>2023-09-13T22:39:40Z</Date> </results> <results> <loc>Loc 11</loc> <loc_name>Loc Desc11</loc_name> <points>4</points> <Date>2023-09-16T22:39:40Z</Date> </results> <results> <loc>Loc 11</loc> <loc_name>Loc Desc11</loc_name> <points>4</points> <Date>2023-09-17T22:39:40Z</Date> </results> <results> <loc>Loc 11</loc> <loc_name>Loc Desc11</loc_name> <points>4</points> <Date>2023-09-18T22:39:40Z</Date> </results> </root>
Groovy实现代码
@Grab('org.codehaus.groovy:groovy-xml:3.0.17') import groovy.xml.XmlSlurper import groovy.xml.MarkupBuilder import java.time.ZonedDateTime import java.time.format.DateTimeFormatter // 输入XML字符串 def inputXml = '''<root> <results> <loc>Loc 10</loc> <loc_name>Loc Desc10</loc_name> <points>3</points> <StartDate>2023-09-11T22:39:40Z</StartDate> <EndDate>2023-09-13T22:45:36.437000Z</EndDate> </results> <results> <loc>Loc 11</loc> <loc_name>Loc Desc 11</loc_name> <points>4</points> <StartDate>2023-09-16T22:39:40Z</StartDate> <EndDate>2023-09-18T22:45:36.437000Z</EndDate> </results> </root>''' // 解析输入XML def rootNode = new XmlSlurper().parseText(inputXml) def formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME // 生成输出XML def writer = new StringWriter() def xmlBuilder = new MarkupBuilder(writer) xmlBuilder.root { rootNode.results.each { result -> // 提取原节点字段 def loc = result.loc.text() def locName = result.loc_name.text() def points = result.points.text() def startDateStr = result.StartDate.text() def endDateStr = result.EndDate.text() // 解析日期 def startDateTime = ZonedDateTime.parse(startDateStr, formatter) def endDateTime = ZonedDateTime.parse(endDateStr, formatter).truncatedTo(java.time.temporal.ChronoUnit.DAYS) // 遍历日期区间内的每一天 def currentDate = startDateTime.truncatedTo(java.time.temporal.ChronoUnit.DAYS) while (!currentDate.isAfter(endDateTime)) { // 拼接当前日期+原开始时间的时分秒 def targetDateTime = currentDate.withHour(startDateTime.hour) .withMinute(startDateTime.minute) .withSecond(startDateTime.second) .withZoneSameInstant(startDateTime.zone) // 生成新的results节点 results { loc(loc) loc_name(locName) points(points) Date(targetDateTime.format(formatter)) } // 日期加1天 currentDate = currentDate.plusDays(1) } } } // 打印输出结果 println writer.toString()
代码说明
- XML解析与生成:使用Groovy内置的
XmlSlurper解析输入XML,MarkupBuilder构建输出XML,无需额外复杂依赖。 - 日期处理:用
ZonedDateTime处理带时区的日期,确保时区一致性;truncatedTo方法截断日期到天级别,避免时分秒干扰区间判断。 - 区间遍历:从
StartDate的日期部分开始,逐天递增直到EndDate的日期部分,为每一天生成对应的<results>节点。 - 字段复用:保留原节点的
loc、loc_name、points字段,替换日期字段为当前遍历到的日期(沿用原StartDate的时分秒)。
内容的提问来源于stack exchange,提问作者N21RL
相关产品推荐
相关产品推荐

