漂亮的 ConfigObject 打印?

发布于 2024-12-12 02:55:40 字数 765 浏览 0 评论 0原文

我有这个 groovy 程序,它使用 ConfigObject 创建一个 groovy 配置文件。设置 ConfigObject 后,将使用以下命令将其写入文件:

myFile.withWriter {writer -> myConfigObject.writeTo(writer)}

这会导致 ConfigObject 的每个属性都写入一行。例如,一张地图将被打印为:

graphs=[["type":"std", "host":"localhost", "name":"cpurawlinux"], ["type":"std", "host":"localhost", "name":"memory"], ["type":"std", "host":"localhost", "name":"udp"] ... ]

如果有人必须看一下它,这是非常不可读的。 有没有办法获得更友好的输出?类似的东西会很棒:

graphs=[
    ["type":"std", "host":"localhost", "name":"cpurawlinux"],
    ["type":"std", "host":"localhost", "name":"memory"],
    ["type":"std", "host":"localhost", "name":"udp"]
    ...
]

我知道我可以创建自己的 writeTo,但是 Groovy 中不是已经有这样的东西了吗?

I have this groovy program that creates a groovy configuration file, using a ConfigObject. Once the ConfigObject is set up, it is written to a file using:

myFile.withWriter {writer -> myConfigObject.writeTo(writer)}

This results in each property of the ConfigObject being written on a single line. So for instance a map will be printed as:

graphs=[["type":"std", "host":"localhost", "name":"cpurawlinux"], ["type":"std", "host":"localhost", "name":"memory"], ["type":"std", "host":"localhost", "name":"udp"] ... ]

which is quite unreadable if someone has to take a look at it.
Is there a way to get a more friendly output? Something like that would be great:

graphs=[
    ["type":"std", "host":"localhost", "name":"cpurawlinux"],
    ["type":"std", "host":"localhost", "name":"memory"],
    ["type":"std", "host":"localhost", "name":"udp"]
    ...
]

I know I could create my own writeTo, but isn't there already something in Groovy for that?

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

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

发布评论

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

评论(4

佞臣 2024-12-19 02:55:40

不幸的是,您需要像您所说的那样编写自己的 writeTo

如果你有一个结构如下的配置文件:

graphs {
  a=["type":"std", "host":"localhost", "name":"cpurawlinux"]
  b=["type":"std", "host":"localhost", "name":"memory"]
}

那么 writeTo 会用结构写出它,但如果你的配置文件只是一个大的旧列表,它会把它写成一个大的旧列表

Unfortunately, you'll need to write your own writeTo as you say.

If you have a config file with structure like:

graphs {
  a=["type":"std", "host":"localhost", "name":"cpurawlinux"]
  b=["type":"std", "host":"localhost", "name":"memory"]
}

Then writeTo will write it out with structure, but if your config file is just a big old list of things, it will write it out as a big old list

似最初 2024-12-19 02:55:40

如果它对任何人有帮助,我有同样的问题并写了这个......不漂亮(哈),但有效:

def prettyPrint(properties, level=1, stringBuilder = new StringBuilder()) {
    return properties.inject(stringBuilder) { sb, name, value ->
        sb.append("\n").append("\t" * level).append(name)
        if (!(value instanceof Map) && !(value instanceof List)) {
            return sb.append("=").append(value)
        } else {
            return prettyPrint(properties.getProperty(name), level+1, sb)
        }
    }
}

if it helps anyone, i had the same question and wrote this...not pretty (ha), but works:

def prettyPrint(properties, level=1, stringBuilder = new StringBuilder()) {
    return properties.inject(stringBuilder) { sb, name, value ->
        sb.append("\n").append("\t" * level).append(name)
        if (!(value instanceof Map) && !(value instanceof List)) {
            return sb.append("=").append(value)
        } else {
            return prettyPrint(properties.getProperty(name), level+1, sb)
        }
    }
}
缱绻入梦 2024-12-19 02:55:40

基于迈克上面的回答:

def prettyPrint
prettyPrint = {obj, level = 0, sb = new StringBuilder() ->
    def indent = { lev -> sb.append("  " * lev) }
    if(obj instanceof Map){
        sb.append("{\n")
        obj.each{ name, value ->
            if(name.contains('.')) return // skip keys like "a.b.c", which are redundant
            indent(level+1).append(name)
            (value instanceof Map) ? sb.append(" ") : sb.append(" = ")
            prettyPrint(value, level+1, sb)
            sb.append("\n")
        }
        indent(level).append("}")
    }
    else if(obj instanceof List){
        sb.append("[\n")
        obj.each{ value ->
            indent(level+1)
            prettyPrint(value, level+1, sb).append(",")
            sb.append("\n")
        }
        indent(level).append("]")
    }
    else if(obj instanceof String){
        sb.append('"').append(obj).append('"')
    }
    else {
        sb.append(obj)
    }
}

对于如下输入:

{
  grails {
    scaffolding {
      templates.domainSuffix = "Instance"
    }
    enable {
      native2ascii = true
      blah = [ 1, 2, 3 ]
    }
    mime.disable.accept.header.userAgents = [ "WebKit", "Presto", "Trident" ]
  }
}

产生:

{
  grails {
    scaffolding {
      templates {
        domainSuffix = "Instance"
      }
    }
    enable {
      native2ascii = true
      blah = [
        1,
        2,
        3,
      ]
    }
    mime {
      disable {
        accept {
          header {
            userAgents = [
              "WebKit",
              "Presto",
              "Trident",
            ]
          }
        }
      }
    }
  }
}

Based on mike's answer above:

def prettyPrint
prettyPrint = {obj, level = 0, sb = new StringBuilder() ->
    def indent = { lev -> sb.append("  " * lev) }
    if(obj instanceof Map){
        sb.append("{\n")
        obj.each{ name, value ->
            if(name.contains('.')) return // skip keys like "a.b.c", which are redundant
            indent(level+1).append(name)
            (value instanceof Map) ? sb.append(" ") : sb.append(" = ")
            prettyPrint(value, level+1, sb)
            sb.append("\n")
        }
        indent(level).append("}")
    }
    else if(obj instanceof List){
        sb.append("[\n")
        obj.each{ value ->
            indent(level+1)
            prettyPrint(value, level+1, sb).append(",")
            sb.append("\n")
        }
        indent(level).append("]")
    }
    else if(obj instanceof String){
        sb.append('"').append(obj).append('"')
    }
    else {
        sb.append(obj)
    }
}

For an input like:

{
  grails {
    scaffolding {
      templates.domainSuffix = "Instance"
    }
    enable {
      native2ascii = true
      blah = [ 1, 2, 3 ]
    }
    mime.disable.accept.header.userAgents = [ "WebKit", "Presto", "Trident" ]
  }
}

Produces:

{
  grails {
    scaffolding {
      templates {
        domainSuffix = "Instance"
      }
    }
    enable {
      native2ascii = true
      blah = [
        1,
        2,
        3,
      ]
    }
    mime {
      disable {
        accept {
          header {
            userAgents = [
              "WebKit",
              "Presto",
              "Trident",
            ]
          }
        }
      }
    }
  }
}
娇女薄笑 2024-12-19 02:55:40

由于 GreenGiant 的答案在我尝试使用它时似乎已损坏,因此这里有一个工作版本以供将来参考:

static String prettify(obj, level = 0, StringBuilder sb = new StringBuilder()) {
    def indent = { lev -> sb.append("  " * lev) }
    if (!obj) return sb
    if(obj instanceof Map<String, ?>){
        sb.append("{\n")
        obj.each{ name, value ->
            if(name.contains('.')) return // skip keys like "a.b.c", which are redundant
            indent(level+1).append(name)
            (value instanceof Map) ? sb.append(" ") : sb.append(" = ")
            prettify(value, level+1, sb)
            sb.append("\n")
        }
        indent(level).append("}")
    } else if(obj instanceof List){
        sb.append("[\n")
        obj.each{ value ->
            indent(level+1)
            prettify(value, level+1, sb).append(",")
            sb.append("\n")
        }
        indent(level).append("]")
    } else if(obj instanceof String){
        sb.append('"').append(obj).append('"')
    } else {
        sb.append(obj)
    }
}

Since GreenGiant answer seems broken when I tried using it, here's a working version for future reference :

static String prettify(obj, level = 0, StringBuilder sb = new StringBuilder()) {
    def indent = { lev -> sb.append("  " * lev) }
    if (!obj) return sb
    if(obj instanceof Map<String, ?>){
        sb.append("{\n")
        obj.each{ name, value ->
            if(name.contains('.')) return // skip keys like "a.b.c", which are redundant
            indent(level+1).append(name)
            (value instanceof Map) ? sb.append(" ") : sb.append(" = ")
            prettify(value, level+1, sb)
            sb.append("\n")
        }
        indent(level).append("}")
    } else if(obj instanceof List){
        sb.append("[\n")
        obj.each{ value ->
            indent(level+1)
            prettify(value, level+1, sb).append(",")
            sb.append("\n")
        }
        indent(level).append("]")
    } else if(obj instanceof String){
        sb.append('"').append(obj).append('"')
    } else {
        sb.append(obj)
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文