【问题标题】:XML to JSON with Groovy XmlSlurper and JsonBuilder使用 Groovy XmlSlurper 和 JsonBuilder 将 XML 转为 JSON
【发布时间】:2014-04-29 20:29:22
【问题描述】:

我正在尝试使用 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()

                }
            }
        }
    }
}

【问题讨论】:

    标签: xml json groovy


    【解决方案1】:

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

    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。如上所示为它们命名。

    【讨论】:

    • 太棒了——你摇滚!
    • 看看我的最后一行为什么你的方法不起作用。我最初忘记添加了。 :) 很高兴它很有帮助。 @JimG
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-11
    相关资源
    最近更新 更多