Groovy中XML响应节点数据的映射

Groovy中XML响应节点数据的映射,groovy,Groovy,我试图将XML响应节点值存储在映射中,但这非常复杂。以下是XML: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <SearchRS> <SearchStatus>SUCCESS</SearchStatus> <Itinerary> <Name>Joe</Name> <Ticket>111

我试图将XML响应节点值存储在映射中,但这非常复杂。以下是XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<SearchRS>
    <SearchStatus>SUCCESS</SearchStatus>
    <Itinerary>
        <Name>Joe</Name>
        <Ticket>111.11</Ticket>
        <Taxes>1.11</Taxes>
    </Itinerary>
    <Itinerary>
        <Name>Bob</Name>
        <Ticket>222.22</Ticket>
        <Taxes>2.22</Taxes>
    </Itinerary>
    <Itinerary>
        <Name>Joe</Name>
        <Ticket>333.33</Ticket>
        <Taxes>3.33</Taxes>
        </Itinerary>
    <Itinerary>
    <Itinerary>
        <Name>Bob</Name>
        <Ticket>444.44</Ticket>
        <Taxes>4.44</Taxes>
    </Itinerary>
        <Name>Joe</Name>
        <Ticket>0.0</Ticket>
        <Taxes>0.0</Taxes>
    </Itinerary>
</SearchRS>
我尝试过的是,这将找到每个文档的最小值,doc.Itinerary保存XML响应

  def minByName = doc.Itinerary
            .inject([:].withDefault { [] }) { map, it ->
       map[it.Name.text()] << it
       map
  }
  .collectEntries { profile, nodes ->
       [profile, nodes.min { it.Ticket.text() as Double }]
  }

  def nameList = []
    minByName.each { profile, minimum ->
        Map nameMap = [:]
        nameMap.name = profile
        nameMap.ticket = minimum.Ticket.toString()
        nameMap.taxes = minimum?.Taxes
        nameList << nameMap
  }
 log.info("Cheapest ticket and tax per name: " + nameList)
我希望地图中的值不是最小值,而是平均值,例如,Joe的所有罚单+税费

看起来是这样的:

[[name:Joe, averageCost:224.44], [name:Bob, averageCost...]]
111.11+1.11=112.22333.33+3.33=336.66。112.22+336.66 = 448.88. 448.88/2=224.44


我真的被困在这一点上了,非常感谢任何帮助

看看这是否是你想要的(解释在线评论):

请找到快捷键

编辑:处理OP的评论

sum()
更改为
sum()。如果我理解正确,第二轮

def root = new XmlSlurper().parse(new File ('/tmp/stack.xml'))

List <String> names = root.'**'.findAll{ it.name() == "Name"}.collect{it}

List <Map> totalresult = []

names.unique().each{name ->

    Map result = [:]

    result["name"] = name

    List<Float> tickets = root.'**'.findAll{ it.Name == name && it.Ticket.toFloat() > 0.0}.collect { it.Ticket.toFloat() + it.Taxes.toFloat() }

    result ["total"] = tickets.sum()

    result ["occurances"]= tickets.size()

    result ["avgCosts"] = result.total/result.occurances

    totalresult.add(result)

}

println totalresult
def root=new-XmlSlurper().parse(新文件('/tmp/stack.xml'))
列表名称=根。'**'.findAll{it.name()==“name”}.collect{it}
List totalresult=[]
names.unique()。每个{name->
映射结果=[:]
结果[“名称”]=名称
List tickets=root.'**'.findAll{it.Name==Name&&it.Ticket.toFloat()>0.0}.collect{it.Ticket.toFloat()+it.Taxes.toFloat()}
结果[“总计”]=tickets.sum()
结果[“发生”]=票证大小()
结果[“avgCosts”]=result.total/result.occurrences
totalresult.add(结果)
}
打印总结果

更新1:根据要求更正代码。

我认为
行程
节点在xml中放错了位置。如果它像我说的那样严格,请更新问题(因为像
name
这样的节点很常见;最好将其保留在特定位置)或随机获取,请检查我的答案。有机会尝试解决方案吗?这很好,但我有一个问题?我如何舍入浮点数?不知道该把球放在哪里。回合(2)…对不起,我没拿到。你能用一个例子来说明这一点吗?感谢大家对有用的答案投赞成票。有了这些代码,我得到了正确值的映射,但需要在小数点后四舍五入。例如[Bob:21.5499999997,Joe:10.67285714285714,Tom:10.406666666667]最好四舍五入到,例如21.54,10.67和10.40,但我不确定放在哪里。四舍五入(2)你可以这样做。顺便说一句,这不是原来的问题,所以我无法想象。@PeterCook,请检查编辑部分以获取您的评论。还可以找到脚本。
[[name:Joe, averageCost:224.44], [name:Bob, averageCost...]]
//pass xmlString to below
def xml = new XmlSlurper().parseText(xmlString)
def map = [:]
//Find unique names, then  respective Iteneraries, then collect ticket & taxes, convert to Double, eliminate 0 values, sum and average, put into map
xml.'**'.findAll {it.name() == 'Name'}.unique().each { name -> 
   map[name] = xml.'**'.findAll {it.name() == 'Itinerary' && name == it.Name.text() }.collect { Double.parseDouble(it.Ticket.text()) + Double.parseDouble(it.Taxes.text())}.findAll {it}.with { sum() / size() }
}
println map
def root = new XmlSlurper().parse(new File ('/tmp/stack.xml'))

List <String> names = root.'**'.findAll{ it.name() == "Name"}.collect{it}

List <Map> totalresult = []

names.unique().each{name ->

    Map result = [:]

    result["name"] = name

    List<Float> tickets = root.'**'.findAll{ it.Name == name && it.Ticket.toFloat() > 0.0}.collect { it.Ticket.toFloat() + it.Taxes.toFloat() }

    result ["total"] = tickets.sum()

    result ["occurances"]= tickets.size()

    result ["avgCosts"] = result.total/result.occurances

    totalresult.add(result)

}

println totalresult