Unmi 学习 Groovy 之 GroovyMarkup (一)

每一种语言都不能忽略了 XML 操作相关的 API,而 Groovy 把使用 XML 的美妙和简易性推向了极致,这就是 GroovyMarkup。它不仅简化了 SAX、DOM 操作,并且把这一理念引入到了 Swing、Swt 界面绘制领域中,Ant、Maven 构建脚本生成中;甚至铺散到更广阔的领域。


Groovy 用闭包和命名参数给标记数据的操作创建通用的语法。GroovyMarkup 在实际的应用中表现为各种 Builder。例如在 Groovy 中内建了以下几个 Builder。

·groovy.xml.MarkupBuilder  --  将你的对象序列化成 XML 或 XHTML
·groovy.xml.SAXBuilder       --  可以用于现有的 SAX 处理器
·groovy.xml.DOMBuilder     --  创建并解析 DOM 文档

而且 GroovyMarkup 语法已经被公认为对操作特定于领域的对象结构很有价值,例如 Ant 文件和 Swing 用户界面。

·groovy.util.AntBuilder        --  用来创建 Ant 构建文件
·groovy.swing.SwingBuilder -- 用来创建 Swing 用户界面
·groovy.util.NodeBuilder      --   创建一般的任意对象的树状结构

除了上面的 Builder,还有第三方的 Builder,例如:

·groovy.swt.SwtBuilder(http://groovy.codehaus.org/GroovySWT)   --  用来创建 SWT 用户界面

应该还能找到其他的第三方构建器,要是明白了构建类的基本原则,你就可以编写自己的构建器。

现在来看一下 Builder 生成 XML 的基本规则,以 MarkupBuilder 为例来说明,如下代码:
1import groovy.xml.MarkupBuilder
2
3xml = new MarkupBuilder();
4xml.users(){
5    user(name:'dejanb',balance:200);
6    user('mike');
7}

上面脚本生成下列输出:

<users>
  <user name='dejanb' balance='200' />
  <user>mike</user>
</users>

代码说明(即构建器的语法规则):

1. MarkupBuilder 的默认构造是输出到控制台,还可以接受其他的参数 IndentPrinter、PrintWriter、Writer,分别指明了不同的输出目的地。所以你可以此控制输出到 Socket 上,或是 Groovlet 的网页上等。

2. MarkupBuilder 的方法名是想当然的,如这里的 users()、user() 方法,它们会生成同名的标签。

3. 如果给调用提供一个 Map 参数,它的元素就表示该标签的参数,如上面的 name:'dejanb',balance:200 命名参数,其实是 [name:'dejanb',balance:200] 的缩写形式。

4. 如果传递一个 Object 参数给方法,它就用作该标签的值,如上面的 mike。

5. 当然也可以既有 Map 参数也有 Object 参数,如写成 user([name:'dejanb',balance:200], 'Unmi'); 生成相应的标签就是(注意这里的中括号不能少了) 
    <user name='dejanb' balance='200'>Unmi</user>

6. 闭包中的方法生成为外层方法(标签) 的子标签,例如,上面的 user() 生成了 users() 对应标签 <users> 的子标签 <user>

接着来体验一下功能更完备的 MarkupBuilder 应用代码:
1import groovy.xml.MarkupBuilder
2
3xml = new MarkupBuilder(new PrintWriter(System.err)); //为了说明 MarkupBuilder 可有不同输出目的地
4xml.users(goal:'sample'){                             //根标签,带 Map 参数
5    user([name:'dejanb',balance:200],'Mike');         //带 Map 和 Object 参数
6    user(name:'Unmi'){                                //带 Map 参数
7        email('fantasia@sina.com');                   //只带 Object 参数
8    }
9}

上面代码输出为:

<users goal='sample'>
  <user name='dejanb' balance='200'>Mike</user>
  <user name='Unmi'>
    <email>fantasia@sina.com</email>
  </user>
</users>

最后应用 MarkupBuilder 生成 XHTML 的例子。
 1import groovy.xml.MarkupBuilder
 2
 3users = ["Mike","Joe"];
 4
 5doc = new MarkupBuilder();
 6doc.html(){
 7    head(){
 8        title("New Balance page");
 9    }
10    body(){
11        table(){
12            users.each(){ user ->
13                doc.tr(){
14                    doc.td(user);
15                }
16            }
17        }
18    }
19}:

生成的 XHTML 代码如下:
<html>
  <head>
    <title>New Balance page</title>
  </head>
  <body>
    <table>
      <tr>
        <td>Mike</td>
      </tr>
      <tr>
        <td>Joe</td>
      </tr>
    </table>
  </body>
</html>
这就是网页了,不过在 Groovlet 中一般还是推荐用模板来实现。

参考:1. 《Java 脚本编程 语言、框架与模式》 第五章,高级的 Groovy 编程 永久链接 https://yanbin.blog/unmi-study-groovy-markup-1/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。