2009-09-24 10 views
4

Je comprends comment créer du XML dans Groovy en utilisant MarkupBuilder. Comment ajouter/insérer des éléments dans un objet MarkupBuilder après la création initiale? Par exemple, commencer par:Ajouter/insérer des éléments dans l'objet Groovy MarkupBuilder après la création initiale

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

qui produirait:

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

Je suis en train de créer un message XML de base extensible, en utilisant une classe de base pour envelopper le constructeur et l'héritage d'ajouter des balises spécifiques. S'appuyant sur l'exemple ci-dessus, voici ma classe de base:

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

Voici un exemple constructeur de message étendu:

Class SubItemBuilder extends ItemBuilder{ 
     def type; 

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

Si je travaillais avec JSON en JavaScript, je ferais quelque chose comme:

items.item.subitem = "foo" 

Je veux finalement SubItemBuilder.getXML générer:

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

Existe-t-il un moyen facile d'y parvenir? Il semble qu'une option consiste à sous-classer MarkupBuilder et à ajouter des méthodes publiques pour insérer des nœuds enfants. Y a-t-il une meilleure approche pour atteindre le résultat que je recherche?

Répondre

6

L'exemple de livre de recettes utilisant MarkupBuilder for Agile XML Creation montre comment créer quelque chose proche de ce dont j'ai besoin.

Par exemple:

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()​ 
+0

Je réalise que cette réponse est assez ancienne mais cela aurait été utile si vous aviez fourni l'extrait de code qui a résolu votre problème. La page que vous avez liée est assez longue et contient un _lot_ de code. +1 pour votre Q et -1 pour cet A. – nickdos

+0

@nickdos J'ai ajouté un extrait de code – elevine

3

Je ne connais pas la réponse mais je vous suggère de restructurer la tentative.

Habituellement, (a) toutes les sorties sont connues au moment de la création du constructeur ou (b) le programme fonctionne dans le cadre de la fermeture du constructeur. Je n'ai pas vu un constructeur utilisé comme un document en soi.

Il existe une autre option: StreamingMarkupBuilder. Cette classe ne construit pas le document tant qu'il n'est pas transmis à un auteur (c'est-à-dire asynchrone). Il rend également plus facile de construire le document à partir de plusieurs sources, comme indiqué ici:

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> 

Je ne pense pas que cela résoudra votre problème cependant. Pouvez-vous reformuler la question avec un peu plus de portée? De cette façon, nous pourrions être en mesure de voir s'il y a un problème philosophique dans l'ensemble.

+0

J'ai effectué ma première question et a ajouté plus de détails. Votre réponse semble être dans la bonne direction, mais pas tout à fait ce dont j'ai besoin. Merci pour l'aide! – elevine