2012-07-09 11 views
5

私はこのコードを持っている "アイデンティティ" タグが欠落していることをGroovyのMarkupBuilderを名の競合

<catalog xmlns='http://www.sybrium.com/XMLSchema/NodeCatalog'> 
    <groupId>sample.group</groupId> 
    <artifactId>sample-artifact</artifactId> 
    <version>1.0.0</version> 
</catalog> 

お知らせを...私はですべてを試してみましたそのノードが表示されるようにします。私は私の髪をリッピングしています!

ありがとうございます。

答えて

11

は、より良い方法があるかもしれません、しかし、1つのトリックは、直接invokeMethodを呼び出すことです:

String buildCatalog(Catalog catalog) { 
    def writer = new StringWriter() 
    def xml = new MarkupBuilder(writer) 
    xml.catalog(xmlns:'http://www.sybrium.com/XMLSchema/NodeCatalog') { 
     delegate.invokeMethod('identity', [{ 
      groupId(catalog.groupId) 
      artifactId(catalog.artifactId) 
      version(catalog.version) 
     }]) 
    } 

    return writer.toString(); 
} 

これは、Groovyのは、舞台裏でやっている効果的にするものです。 delegate.identityまたはowner.identityを正常に動作させることができませんでした。


編集:私は何が起こっている考え出しました。

Groovy adds a methodすべてのオブジェクトにidentity(Closure c)の署名が付いています。

これは、動的にXMLビルダにidentity要素を起動しようとしたとき、単一の閉鎖引数に渡しながら、それは外側の閉鎖にdelegate({...})を呼び出すようなものですidentity()メソッドを呼び出したことを意味します。

invokeMethodトリックを使用すると、MetaObjectプロトコルがバイパスされ、identityメソッドがすでにMetaObjectに存在していても、そのメソッドを動的メソッドとして扱うことができます。

これを知ると、わかりやすくわかりやすいソリューションをまとめることができます。

String buildCatalog(Catalog catalog) { 
    def writer = new StringWriter() 
    def xml = new MarkupBuilder(writer) 
    xml.catalog(xmlns:'http://www.sybrium.com/XMLSchema/NodeCatalog') { 
     // NOTE: LEAVE the empty map here to prevent calling the identity method! 
     identity([:]) { 
      groupId(catalog.groupId) 
      artifactId(catalog.artifactId) 
      version(catalog.version) 
     } 
    } 

    return writer.toString(); 
} 

これは、はるかに読みやすいです、それは明確の意図、およびコメントは(たぶん)「不要」空を削除するから誰を防ぐ必要があります。私たちがしなければならないので、同様に、メソッドのシグネチャを変更で地図。

+0

これはうまくいきましたが、これを説明できますか?デリゲートとは何ですか?また、delegate.identityとdelegate.invokeMethod( 'identity')との違いは何ですか? –

+0

私はそれを理解した、私は私の答えを更新します。 – OverZealous

+0

FYI:GroovyConsoleを使用してXMLオブジェクトを検査してこれを追跡しました。これは、単一の 'Closure'を引数として' identity'メソッドが既に存在していたことを私に知らせます。 – OverZealous

関連する問題