初始创建后将元素添加/插入到 Groovy MarkupBuilder 对象中

发布于 2024-08-05 20:36:44 字数 1259 浏览 4 评论 0原文

我了解如何使用 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 并添加公共方法来插入子节点。有没有更好的方法来实现我正在寻找的结果?

I understand how to create XML in Groovy using MarkupBuilder. How do you add/insert elements into a MarkupBuilder object after the initial creation? For example, start with:

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

Which would produce:

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

I am trying to create an extensible base XML message, using a core class to wrap the builder and inheritance to add specific tags. Building on the above example, here is my base class:

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

Here is an example extended message builder:

Class SubItemBuilder extends ItemBuilder{
       def type;

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

If I was working with JSON in JavaScript, I would do something like:

items.item.subitem = "foo"

I ultimately want SubItemBuilder.getXML to generate:

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

Is there any easy way to achieve this? Seems like one option is to subclass MarkupBuilder and add public methods to insert child nodes. Is there a better approach to achieve the result I'm looking for?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小忆控 2024-08-12 20:36:44

使用 MarkupBuilder 进行敏捷 XML 创建 的食谱示例展示了如何创建接近我需要的东西。

例如:

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

The cookbook example Using MarkupBuilder for Agile XML Creation shows how to create something close to what I need.

For example:

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()​
原谅过去的我 2024-08-12 20:36:44

我不知道答案,但我建议你重新调整尝试。

通常,(a) 所有输出在创建构建器时已知,或者 (b) 程序在构建器闭包的范围内运行。我还没有看到构建器本身用作文档。

还有另一种选择: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>

不过,我认为这不会解决您的问题。你能以更大的范围重新表述这个问题吗?这样,我们也许能够看到更大的图景是否存在哲学问题。

I don't know the answer but I suggest that you restructure the attempt.

Usually, either (a) all output is known at the time of creating the builder or (b) the program operates within the scope of the builder's closure. I haven't seen a builder used as a document per se.

There is one other option: the StreamingMarkupBuilder. This class doesn't construct the doc until it is handed off to a writer (i.e. asynchronous). It also makes it easier to construct the doc from multiple sources, as shown here:

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>

I don't think this will solve your problem though. Can you rephrase the question with a bit more scope? That way, we might be able to see if there is a philosophical issue with the larger picture.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文