Groovy 将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){

想象一下用于表示对象层次结构的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生成的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)
      }
    }
  ]
}
如果无法调整基类,请在构建图形之前