2016-07-19 54 views
0

內調用方法,我有一個使用Groovy的MarkupBuilder的打印HTML,下面非常簡化的版本簡單的Groovy方法:從一個Groovy DSL

void writeHtmlFile(<args>) { 
    def writer = new FileWriter(fileName.toFile()) 
    def html = new MarkupBuilder(writer) 

    html.mkp.yieldUnescaped '<!DOCTYPE html>' 
    html.mkp.xmlDeclaration(version: "1.0", encoding: "utf-8") 
    html.html { 
    head { ... } 
    body(id: 'main') { 
     h1 "Report Title" 
    }  
    } 
    writer.flush() 
    writer.close() 
} 

這種運作良好。假設我想在h1之後調用一個方法來進行一些計算,並將更多內容添加到MarkupBuilder中。我怎樣才能將被調用方法中定義的元素添加到MarkupBuilder中?這裏的東西我想,不會引起異常,但也不起作用(HTML結果沒有<h2>元素):

Closure testNested() { 
    println '---' 
    return { h2 "here's a subheading" } 
} 

// .... other stuff from above example not repeated ... 
html.html { 
    head {...} 
    body(id: 'main') { 
     h1 "Report Title" 
     testNested() 
    }  

我知道我可以很容易地做到這一點在線。我試圖加深對Groovy如何在DSL中使用閉包和代理的理解,並且顯然我錯過了一些東西。

回答

1

考慮下面的代碼,它使用Groovy 2.4.5可以很好地執行。

構建器模式有點棘手,因爲它可以視爲分層數據和/或代碼,具體取決於您的視角。通過練習,可以根據需要切換視角。

import groovy.xml.* 

void testNested(def html) { 
    html.h2("here's a subheading from testNested") 
} 

void writeHtmlFile(def fileName) { 
    def writer = new FileWriter(fileName) 
    def html = new MarkupBuilder(writer) 

    html.mkp.yieldUnescaped '<!DOCTYPE html>' 
    html.mkp.xmlDeclaration(version: "1.0", encoding: "utf-8") 
    html.html { 
    body(id: 'main') { 
     h1 "Report Title" 
     testNested(html) 
    } 
    } 
    writer.flush() 
    writer.close() 
} 

writeHtmlFile("out.html")