【问题标题】:Calling a method from inside StreamingMarkupBuilder从 StreamingMarkupBuilder 内部调用方法
【发布时间】:2014-05-05 18:36:43
【问题描述】:

我正在使用 Groovy 的 StreamingMarkupBuilder 根据几个 SQL 查询的结果动态生成 XML。我想从闭包内部调用一个方法,但标记生成器尝试使用方法名称创建一个 XML 节点。

这是我正在尝试做的一个示例:

Map generateMapFromRow(GroovyRowResult row) {
  def map = [:]
  def meta = row.getMetaData()

  // Dynamically generate the keys and values
  (1..meta.getColumnCount()).each { column -> map[meta.getColumnName(column)] = row[column-1] }
  return map
}

def sql = Sql.newInstance(db.url, db.user, db.password, db.driver)
def builder = new StreamingMarkupBuilder()

def studentsImport = {
  students {
    sql.eachRow('select first_name, middle_name, last_name from students') { row ->
      def map = generateMapFromRow(row) // Here is the problem line
      student(map)
    }
  }
}

println builder.bind(studentsImport).toString()

这将生成类似于以下内容的 XML:

<students>
  <generateMapFromRow>
    [first_name:Ima, middle_name:Good, last_name:Student]
  </generateMapFromRow>
  <student/>
  <generateMapFromRow>
    [first_name:Ima, middle_name:Bad, last_name:Student]
  </generateMapFromRow>
  <student/>
</students>

我已经尝试将方法移出一个类并在该类上静态调用,这也不起作用。

由于 StreamingMarkupBuilder 工作方式的性质,我担心实际上不可能做到这一点,但我希望它是。

【问题讨论】:

    标签: java xml groovy markupbuilder streamingmarkupbuilder


    【解决方案1】:

    在示例简化过程中我可能会松懈,但这样的代码会起作用。

    在您的示例中,students 是一个闭包调用,所以它可能会在里面弄乱。

    def builder = new groovy.xml.StreamingMarkupBuilder()
    def generateMapFromRow = { ["$it": it] }
    builder.bind {
    10.times {
        def map = generateMapFromRow(it) // Now closure is escaped, there is local variable with such name.
        student(map)
        }
    }
    

    如这里所说:http://groovy.codehaus.org/Using+MarkupBuilder+for+Agile+XML+creation

    使用标记构建器时要注意的事项是不要重叠您当前在范围内的变量。下面是一个很好的例子

    import groovy.xml.MarkupBuilder
    
    def book = "MyBook"
    
    def writer = new StringWriter()
    def xml = new MarkupBuilder(writer)
    xml.shelf() {
        book(name:"Fight Club") { // Will produce error.
        }
    }
    
    println writer.toString()
    

    Builder 的工作类似于 MethodMissing Captors,如果作用域中有局部变量,则不会产生节点。

    【讨论】:

    • 感谢您的信息。看起来问题实际上源于我的示例中的这一行:Map generateMapFromRow(GroovyRowResult row)。由于某种原因,删除显式 GroovyRowResult 类型使其正常工作。不过,您的回答使我弄清楚了这一点,因此我将其标记为已接受。干杯!
    • @caseyscarborough 我很高兴为您提供帮助。请花一点时间并在您的答案中包含该信息,以使其对未来的读者有用。
    猜你喜欢
    • 2016-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多