想象一下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){
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生成的发票对象实际转换为Invoice类的实例,其中包含从发票对象配置的所有内容?我可能必须使用GPath来执行此操作(?)但该代码将如何显示?
我需要这样做的原因是其他类的其他方法需要Invoice类的实例进一步操作,我猜不会接受NodeBuilder输出。
答案 0 :(得分:2)
我认为最简单的方法就是为您的特定对象集进行节点遍历。
示例:
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
}
}
答案 1 :(得分:1)
对您的基类进行轻微调整:
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)
}
}
]
}
如果无法调整基类,则在构建图表之前can customise how properties are looked up by setting the resolvers