我是 groovy 的新手。我正在尝试使用 groovy 重新格式化 XML。 我正在为 orderstartdate 和 StartDate 之间的每个日期创建 XML 节点。但子节点(prod)之一具有子节点(id 和 count),并且这些子节点未正确附加。 我正在尝试以下代码。
`
import java.text.*
import groovy.xml.*
SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd")
String orderstartdate = "2023-10-12T18:32:21Z";
Date orderstart = parser.parse( orderstartdate )
def text = '''
<results>
<orderid>4ff45676-f77e-430a-ba7d-e02a20303c0d</orderid>
<StartDate>2023-10-16T18:00:00Z</StartDate>
<prod>
<id>a-6210q</id>
<count>17</count>
</prod>
<prod>
<id>a-1110w</id>
<count>17</count>
</prod>
</results>
'''
def xml = new XmlSlurper().parseText( text )
def output = new XmlParser().parseText("<root/>")
xml.each { eachXmlNode ->
Date startDate = parser.parse( orderstartdate )
Date endDate = parser.parse( eachXmlNode.StartDate.text() )
Date currentDate = new Date( startDate.time )
while( currentDate < endDate ) {
Node resultsNode = output.appendNode( new QName("results"), [:] )
eachXmlNode.children().findAll { child -> child.name() != "StartDate" } .each { child ->
resultsNode.appendNode( new QName(child.name()), [:], child.text() )
}
resultsNode.appendNode(new QName("Date"), [:], parser.format( currentDate ))
currentDate = currentDate + 1
}
}
println( XmlUtil.serialize(output ) )
`
我用上面的代码得到的输出: `
<results xmlns="">
<orderid>4ff45676-f77e-430a-ba7d-e02a20303c0d</orderid>
<prod>a-6210q17</prod>
<prod>a-1110w17</prod>
<Date>2023-10-12</Date>
</results>
<results xmlns="">
<orderid>4ff45676-f77e-430a-ba7d-e02a20303c0d</orderid>
<prod>a-6210q17</prod>
<prod>a-1110w17</prod>
<Date>2023-10-13</Date>
</results>
<results xmlns="">
<orderid>4ff45676-f77e-430a-ba7d-e02a20303c0d</orderid>
<prod>a-6210q17</prod>
<prod>a-1110w17</prod>
<Date>2023-10-14</Date>
</results>
<results xmlns="">
<orderid>4ff45676-f77e-430a-ba7d-e02a20303c0d</orderid>
<prod>a-6210q17</prod>
<prod>a-1110w17</prod>
<Date>2023-10-15</Date>
</results>
</root>
`
我期望的输出: `
<results xmlns="">
<orderid>4ff45676-f77e-430a-ba7d-e02a20303c0d</orderid>
<prod>
<id>a-6210q</id>
<count>17</count>
</prod>
<prod> <id>a-1110w</id>
<count>17</count>
</prod>
<Date>2023-10-12</Date>
</results>
<results xmlns="">
<orderid>4ff45676-f77e-430a-ba7d-e02a20303c0d</orderid>
<prod>
<id>a-6210q</id>
<count>17</count>
</prod>
<prod> <id>a-1110w</id>
<count>17</count>
</prod
<Date>2023-10-13</Date>
</results>
<results xmlns="">
<orderid>4ff45676-f77e-430a-ba7d-e02a20303c0d</orderid>
<prod>
<id>a-6210q</id>
<count>17</count>
</prod>
<prod> <id>a-1110w</id>
<count>17</count>
</prod
<Date>2023-10-14</Date>
</results>
<results xmlns="">
<orderid>4ff45676-f77e-430a-ba7d-e02a20303c0d</orderid>
<prod>
<id>a-6210q</id>
<count>17</count>
</prod>
<prod> <id>a-1110w</id>
<count>17</count>
</prod
<Date>2023-10-15</Date>
</results>
</root>
`
您知道需要在此处添加什么才能获得正确的格式吗?
所以,你可以这样做:
import groovy.xml.MarkupBuilder
import groovy.xml.XmlSlurper
import java.time.ZonedDateTime
def xml = new XmlSlurper().parseText(text)
def orderStartDate = ZonedDateTime.parse("2023-10-12T18:32:21Z").toLocalDate()
def endDate = ZonedDateTime.parse(xml.StartDate.text()).toLocalDate()
def orderId = xml.orderid.text()
def writer = new StringWriter()
new MarkupBuilder(writer).root {
(orderStartDate..<endDate).each { d ->
results {
orderid(orderId)
date(d.toString())
xml.prod.each { p ->
prod {
id(p.id.text())
count(p.count.text())
}
}
}
}
}
println writer.toString()
这样就可以迭代一系列 LocalDate,并使用 MarkupBuilder 创建一些 XML
该脚本的输出是:
<root>
<results>
<orderid>4ff45676-f77e-430a-ba7d-e02a20303c0d</orderid>
<date>2023-10-12</date>
<prod>
<id>a-6210q</id>
<count>17</count>
</prod>
<prod>
<id>a-1110w</id>
<count>17</count>
</prod>
</results>
<results>
<orderid>4ff45676-f77e-430a-ba7d-e02a20303c0d</orderid>
<date>2023-10-13</date>
<prod>
<id>a-6210q</id>
<count>17</count>
</prod>
<prod>
<id>a-1110w</id>
<count>17</count>
</prod>
</results>
<results>
<orderid>4ff45676-f77e-430a-ba7d-e02a20303c0d</orderid>
<date>2023-10-14</date>
<prod>
<id>a-6210q</id>
<count>17</count>
</prod>
<prod>
<id>a-1110w</id>
<count>17</count>
</prod>
</results>
<results>
<orderid>4ff45676-f77e-430a-ba7d-e02a20303c0d</orderid>
<date>2023-10-15</date>
<prod>
<id>a-6210q</id>
<count>17</count>
</prod>
<prod>
<id>a-1110w</id>
<count>17</count>
</prod>
</results>
</root>
我认为是你想要的?
所以你只想克隆树中的节点。不幸的是,Groovy 没有一个很好的克隆方法可供我们使用,因此我们将通过序列化节点来使用一些解决方法。这不是高性能的,如果您正在处理大型文档,您可能会采取额外的步骤,为您想要移动的每个内容创建一个节点,并编写更长的形式代码,以提高性能。但内循环看起来像这样:
eachXmlNode.children().findAll { child -> child.name() != "StartDate" } .each { child ->
def clonedNode = new XmlParser().parseText( XmlUtil.serialize( child ) )
resultsNode.append( clonedNode )
}
另一种方法是用手写出来,例如:
eachXmlNode.children().findAll { child -> child.name() != "StartDate" } .each { child ->
switch( child.name() ) {
case "prod":
resultsNode.appendNode( "prod", [:] ).with { prodNode ->
prodNode.appendNode( "id", [:], child.id.text() )
prodNode.appendNode( "count", [:], child.count.text() )
}
break
default:
resultsNode.appendNode( child.name(), [:], child.text() )
break
}
}