使用Groovy中的XML MarkupBuilder动态添加多个XML元素/容器。

12

我正在尝试使用Groovy MarkupBuilder生成XML。

所需的XML格式如下(简化):

<Order>
  <StoreID />
  <City />
  <Items>
    <Item>
      <ItemCode />
      <UnitPrice />
      <Quantity />
    </Item>
  </Items>
</Order>
数据存储在Excel文件中,易于访问。我的Groovy脚本解析Excel并生成XML。
例如。
import groovy.xml.*
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)

xml.Order{
  StoreID("Store1")
  City("New York")
  Items(){
    Item(){
      ItemCode("LED_TV")
      UnitPrice("800.00")
      Quantity("2")
    }
  }
}

"items" 容器内可以有多个 "item" 容器。

我的问题是: 假设我们想生成包含 10 个项目的订单 XML。是否有一种方法可以在 "items" 容器内编写类似于 for 循环的代码?这样,我们就不需要为 10 个不同的项目编写 MarkupBuilder 代码。

有一个类似的问题 Adding dynamic elements and attributes to groovy MarkupBuilder or StreamingMarkupBuilder。但它没有讨论循环。

2个回答

23

是的,有一种使用循环的方法。在此扩展您的示例:

import groovy.xml.*
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)

//List of items represented as a map
def items = [[itemCode: "A", unitPrice: 10, quantity: 2], 
             [itemCode: "B", unitPrice: 20, quantity: 3], 
             [itemCode: "C", unitPrice: 30, quantity: 4], 
             [itemCode: "D", unitPrice: 40, quantity: 6], 
             [itemCode: "E", unitPrice: 50, quantity: 5]]

xml.Order{
  StoreID("Store1")
  City("New York")
  Items{
    //Loop through the list.
    //make sure you are using a variable name instead of using "it"
    items.each{item->
      Item{
        ItemCode(item.itemCode)
        UnitPrice(item.unitPrice)
        Quantity(item.quantity)
      }
    }
  }
}

println writer

应该能够给你想要的东西。


我明白了。所以我们可以在标记内编写常规的Groovy循环代码。我原以为标记应该只包含标记代码。感谢您详细的回答。非常感激! :) - CodeVenture
谢谢您的建议。这对我节省了很多精力。 - Tung
感谢您的精彩回答!作为一个Groovy新手,我搜索了很多,直到找到了这个! - eerriicc

2

这篇文章帮助我解决了一个类似的问题:我想在MarkupBuilder块中调用函数,比如我的例子中的addElement()函数。

我想把代码拆分成不同的函数。

在MarkupBuilder块中调用函数的示例:

static void addElement(Map<String,String> elements, MarkupBuilder mb) {
    mb."${elements.tag}"(elements.content)
}

static void example() {
    def writer = new StringWriter()
    def htmlBuilder = new MarkupBuilder(writer)

    String tag = "a"
    Map<String, String> attributes1 = new HashMap<>()
    attributes1.put("href","http://address")
    String content1 = "this is a link"

    Map<String, String> element1 = new HashMap<>()
    element1.put("tag","b")
    element1.put("content","bold content 1")

    Map<String, String> element2 = new HashMap<>()
    element2.put("tag","b")
    element2.put("content","bold content 2")

    List<Map<String, String>> elements = new ArrayList<>()
    elements.add(element1)
    elements.add(element2)

    htmlBuilder."html" {
        "${tag}"( attributes1, content1 )
        elements.each { contentIterator ->
            addElement(contentIterator, htmlBuilder)
        }
    }

    println writer
 }

并且它会产生以下输出:
<html>
  <a href='http://address'>this is a link</a>
  <b>bold content 1</b>
  <b>bold content 2</b>
</html>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接