4

MarkupBuilder を使用して Groovy で XML を作成する方法を理解しています。最初の作成後に MarkupBuilder オブジェクトに要素をどのように追加/挿入しますか? たとえば、次のように開始します。

def builder = new MarkupBuilder(writer)
  def items = builder.items{
        item(name: "book")
  }

どちらが生成されますか:

<items> 
   <item name="book/> 
 </items>

コア クラスを使用してビルダーをラップし、継承を使用して特定のタグを追加して、拡張可能な基本 XML メッセージを作成しようとしています。上記の例に基づいて、これが私の基本クラスです。

Class ItemBuilder{
   def name;
   def builder = new MarkupBuilder(writer)
   public Object getXML(){
     def items = builder.items{
            item(name: this.name)
      }
     return items;
   }
}

拡張メッセージ ビルダーの例を次に示します。

Class SubItemBuilder extends ItemBuilder{
       def type;

       public Object getXML(){
         def items = super.getXML();
         //do something here to add a subitem child tag....
         return items;
       }
    }

JavaScript で JSON を扱う場合は、次のようにします。

items.item.subitem = "foo"

私は最終的に SubItemBuilder.getXML が生成することを望んでいます:

<items> 
     <item name="book>
       <subitem type="paperback"/>
      </item>
 </items>

これを達成する簡単な方法はありますか?MarkupBuilder をサブクラス化し、パブリック メソッドを追加して子ノードを挿入するのが 1 つのオプションのようです。私が探している結果を達成するためのより良いアプローチはありますか?

4

2 に答える 2

7

クックブックの例 Using MarkupBuilder for Agile XML Creationは、私が必要としているものに近いものを作成する方法を示しています。

例えば:

import groovy.xml.MarkupBuilder

def writer = new StringWriter()
def builder = new MarkupBuilder(writer)  

def subitem (builder){
    builder.subitem(type: "paperback")
}


def items = builder.items{
    item(name: "book")
    subitem(builder)
}

println writer.toString()​
于 2012-02-26T16:05:24.227 に答える
3

答えはわかりませんが、試みを再構築することをお勧めします。

通常、(a) ビルダーの作成時にすべての出力が既知であるか、(b) プログラムがビルダーのクロージャーの範囲内で動作します。ビルダー自体がドキュメントとして使用されているのを見たことがありません。

もう 1 つのオプションがあります: StreamingMarkupBuilder です。このクラスは、ドキュメントがライターに渡されるまで (つまり、非同期で) ドキュメントを構築しません。次に示すように、複数のソースからドキュメントを簡単に作成することもできます。

import groovy.xml.*

def builder = new StreamingMarkupBuilder()

def item1 = { item(name:'book') }
def item2 = { item(name:'mag') }

def doc = { 
    "items" {
        out << item1
        out << item2
    }
}

println builder.bind(doc)

>>> <items><item name='book'/><item name='mag'/></items>

ただし、これで問題が解決するとは思いません。もう少し範囲を広げて質問を言い換えることができますか? そうすれば、全体像に哲学的な問題があるかどうかを確認できるかもしれません。

于 2009-09-24T02:19:27.427 に答える