使用Groovy XmlSlurper和JsonBuilder的XML到JSON

时间:2014-04-29 20:29:22

标签: xml json groovy

我正在尝试使用Groovy获取XML文件并将其转换为JSON文档,特别是使用XmlSlurper和JsonBuilder。如果我对所有内容进行硬编码,我可以相当容易地做到这一点,但如果可能,我宁愿不这样做。

以下是XML的一个示例 - 在现实生活中结构是相同的,但有数百个节点。

<root>
  <data>
      <node1>
          <child1>1</child1>
          <child2>2</child2>
          <child3>3</child3>
      </node1>
      <node2>
          <child1>1</child1>
          <child2>2</child2>
          <child3>3</child3>
      </node2>
  </data>
</root>

我想将此映射到以下JSON:

{
    "type": "test",
    "time": {
        "$date": timestamp
    },
    "data": {
        "node1": {
            "child1": 1,
            "child2": 2,
            "child3": 3
        },
        "node2": {
            "child1": 1,
            "child2": 2,
            "child3": 3
        }
    }
}

我当前的代码看起来像这样(感谢@dmahapatro):

def parser = new XmlSlurper().parse("file.xml")

def getNode = {String parentNode, String childNode ->
    parser.data."$parentNode"
               ."$childNode"
               .find { it.name() == childNode }
}

def root = json {
    type "test"
    time { $date timestamp }
    data {
        node1 {
            child1 getNode("node1","child1").toInteger()
            child2 getNode("node1","child2").toInteger()
            child3 getNode("node1","child3").toInteger()
        }
        node2 {
            child1 getNode("node1","child1").toInteger()
            child2 getNode("node1","child2").toInteger()
            child3 getNode("node1","child3").toInteger()
        }
    }
}

我想要做的是遍历XML并在JSON文档中动态创建节点。考虑到我有数百个节点要在现实生活中处理硬编码这些都进入JsonBuilder并不是很理想。我尝试过以下操作,但它无法正常工作。希望它会让你知道我想要的方向:

def json = new JsonBuilder()
def root = json {
    type "test"
    time { $date timestamp }
    data {
        parser.data.childNodes().each {
            it.name {

                it.childNodes().each {
                it.name it.text()

                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:2)

这个怎么样? :)这是我在上一个问题中的最后一行。

def xml='''
<root>
  <data>
      <node1>
          <child1>1</child1>
          <child2>2</child2>
          <child3>3</child3>
      </node1>
      <node2>
          <child1>1</child1>
          <child2>2</child2>
          <child3>3</child3>
      </node2>
  </data>
</root>
'''

def slurper = new XmlSlurper().parseText(xml)

def builder = new groovy.json.JsonBuilder()
builder {
    type 'record'
    time { $date 'timestamp' }
    data {
        slurper.data.childNodes().each { nodeElem ->
            "$nodeElem.name" {
                nodeElem.childNodes().each { childElem ->
                    "$childElem.name" childElem.text().toInteger()
                }
            }
        }
    }
}

builder.toPrettyString()

如果存在子元素值不是整数的情况,则可以使用以下代码:

childElem.text().isNumber() ? childElem.text().toInteger() : childElem.text()

忘了提到你的方法不起作用的要点。 it是立即包装闭包的隐式变量。在您的情况下,您有3个闭包,每个地方都使用it。如上所示命名它们。