Groovy 将NodeBuilder结果转换为对象层次结构
想象一下用于表示对象层次结构的nodeBuilder:Groovy 将NodeBuilder结果转换为对象层次结构,groovy,Groovy,想象一下用于表示对象层次结构的nodeBuilder: class TestBuilder { static main(args) { def builder = new NodeBuilder() def ulcDate = new Date(107,0,1) def invoices = builder.invoices{ invoice(date: ulcDate){ item(count:5){
class TestBuilder {
static main(args) {
def builder = new NodeBuilder()
def ulcDate = new Date(107,0,1)
def invoices = builder.invoices{
invoice(date: ulcDate){
item(count:5){
product(name:'ULC', dollar:1499)
}
item(count:1){
product(name:'Visual Editor', dollar:499)
}
}
invoice(date: new Date(106,1,2)){
item(count:4) {
product(name:'Visual Editor', dollar:499)
}
}
}
}
class Invoice {
List items
Date date
}
class LineItem {
Product product
int count
int total()
{
return product.dollar * count
}
}
class Product {
String name
def dollar
}
如何将NodeBuilder生成的invoices对象转换为invoices类的实例,并从invoices对象配置所有内容?我可能必须使用GPath来执行此操作(?),但该代码是什么样子的
我需要这样做的原因是,其他类的其他方法需要Invoice类的实例来进一步操作,并且我猜不会接受NodeBuilder输出。我认为最简单的方法就是对特定对象集执行节点遍历 例如:
import groovy.util.*
////////////
// build Node tree as asked in original post
def builder = new NodeBuilder()
def ulcDate = new Date(107,0,1)
def invoices = builder.invoices {
invoice(date: ulcDate) {
item(count:5) {
product(name:'ULC', dollar:1499)
}
item(count:1) {
product(name:'Visual Editor', dollar:499)
}
}
invoice(date: new Date(106,1,2)){
item(count:4) {
product(name:'Visual Editor', dollar:499)
}
}
}
////////////
// define objects. It is easy to have these in Java
class Invoice {
def date
def items = []
}
class Item {
def count
def product
}
class Product {
def name
def dollar
}
////////////
// convert from nodes to objects
def invoiceNodeList = invoices.get("invoice")
def invoiceList = []
invoiceNodeList.each { def invoiceNode ->
def date = invoiceNode.attribute("date")
Invoice invoice = new Invoice(date: date)
invoiceNode.children().each { def itemNode ->
def count = itemNode.attribute("count")
Product product = null
// assume only one Product per Item, but we'll
// use children() for simplicity
itemNode.children().each { def productNode ->
def name = productNode.attribute("name")
def dollar = productNode.attribute("dollar")
product = new Product(name: name, dollar: dollar)
}
Item item = new Item(count: count, product: product)
invoice.items << item
}
invoiceList << invoice
}
////////////
// print out objects
invoiceList.each { Invoice invoice ->
println "--------"
println invoice.date
invoice.items.each { Item item ->
println item.count
println item.product.name
println item.product.dollar
}
}
导入groovy.util*
////////////
//按照原始帖子中的要求构建节点树
def builder=新节点生成器()
def ulcDate=新日期(107,0,1)
def invoices=builder.invoices{
发票(日期:ulcDate){
项目(计数:5){
产品(名称:ULC,美元:1499)
}
项目(计数:1){
产品(名称:'VisualEditor',美元:499)
}
}
发票(日期:新日期(106,1,2)){
项目(计数:4){
产品(名称:'VisualEditor',美元:499)
}
}
}
////////////
//定义对象。在Java中很容易实现这些功能
类别发票{
定义日期
def项目=[]
}
类项目{
def计数
def产品
}
类产品{
定义名称
def美元
}
////////////
//从节点转换为对象
def invoiceNodeList=invoices.get(“发票”)
def发票列表=[]
invoiceNodeList.each{def invoiceNode->
def date=invoiceNode.attribute(“日期”)
发票=新发票(日期:日期)
invoiceNode.children()。每个{def itemNode->
def count=itemNode.attribute(“count”)
Product=null
//假设每个项目只有一种产品,但我们将
//为了简单起见,请使用children()
itemNode.children()。每个{def productNode->
def name=productNode.attribute(“名称”)
def dollar=productNode.attribute(“美元”)
产品=新产品(名称:名称,美元:美元)
}
项目=新项目(计数:计数,产品:产品)
发票项
println item.count
println item.product.name
println item.product.dollar
}
}
稍微调整一下基类:
class Invoice {
List lineItems = []
Date date
String toString() {
String ret = "Invoice $date $lineItems"
}
}
class LineItem {
Product product
int count
int total() {
product.dollar * count
}
String toString() {
"$product * $count"
}
}
class Product {
String name
int dollar
String toString() {
"$name ($dollar)"
}
}
意味着您可以轻松使用ObjectGraphBuilder
构建列表:
List invoices = new ObjectGraphBuilder(classLoader: getClass().classLoader).with {
[
invoice( date: new Date( 107, 0, 1 ) ) {
lineItem( count: 5 ) {
product( name: 'ULC', dollar: 1499 )
}
lineItem(count:1){
product(name:'Visual Editor', dollar:499)
}
},
invoice(date: new Date(106,1,2)){
lineItem(count:4) {
product(name:'Visual Editor', dollar:499)
}
}
]
}
如果无法调整基类,请在构建图形之前