Add/append 使用 snakeYaml 的 YAML 文件中的内部(嵌套)键值

Add/append inner(nested) key-value in an YAML file using snakeYaml

我有一个可能有也可能没有“上下文:”的 yaml 文件。

我的目标是: (1) 添加“contexts:”(如果它尚不存在)。 即,如果文件没有“上下文:”,如下所示

api:
    - endpoint: /myapp

==> 然后添加 v2 上下文

api:
    - endpoint: /myapp
    contexts:
    - version: v2
      deprecated: "false"

(2) 如果“上下文:”已经存在,则添加版本 v2 上下文。 即如果文件有任何“上下文:”如下所示

api:
    - endpoint: /myapp
    contexts:
    - version: v1
      deprecated: "true"

==> 然后添加 v2 上下文

api:
    - endpoint: /myapp
    contexts:
    - version: v1
      deprecated: "true"
    - version: v2
      deprecated: "false"

我想出了这个脚本。它适用于案例 #1,但不适用于案例 #2。对于案例 #2,它再次添​​加 v1 和 v2。

import org.yaml.snakeyaml.DumperOptions
import org.yaml.snakeyaml.Yaml

import org.yaml.snakeyaml.nodes.Tag
import org.yaml.snakeyaml.representer.Representer

import java.io.File
import java.io.FileInputStream
import java.io.FileWriter
import java.io.IOException
import java.io.InputStream
import java.util.ArrayList
import java.util.HashMap
import java.util.List
import java.util.Map

DumperOptions options = new DumperOptions()
options.setIndent( 2 )
options.setIndicatorIndent( 0 )
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK)

Yaml yaml = new Yaml(options)

final String fileName = "/temp/rest.yaml"
File myappFile = new File (fileName)
Map<String , Object> myappMap = (Map<String, Object>) yaml.load(myappFile.text)

    
if (!(myappMap.containsKey("contexts"))) {
    Map<String, Object> btlContext = new LinkedHashMap<String, Object>()
    btlContext.put( "version", "v2" )
    btlContext.put( "deprecated", "false" )
    
    List<Map<String, Object>> list = new ArrayList<>()
    list.add(btlContext)
    
    Map<String, List<Map<String, Object>>> config = new HashMap<>()
    config.put( "contexts", list )
    
    FileWriter writer = new FileWriter(fileName, true)
    yaml.dump( config, writer )
    
}else{

    boolean foundBtlContext = false
    System.out.println(myappMap.get("contexts"))

    List<Map<String, Object>> sourceContexts = (List<Map<String, Object>>) myappMap.get("contexts")

    for(Map<String, Object> m : sourceContexts) {
       if( m.get('version').toString().equals('v2') ){
           foundBtlContext = true
           break
       }
    }

    if (!foundBtlContext){
        Map<String, Object> btlContext = new LinkedHashMap<String, Object>()
        btlContext.put( "version", "v2" )
        btlContext.put( "deprecated", "false" )
        
        sourceContexts.add(btlContext)
        
        FileWriter writer = new FileWriter(fileName, true)
        yaml.dump(sourceContexts, writer )
    }
}

对于 #2,脚本再次添加 v1,如下所示:

api:
- endpoint: /myapp
contexts:
- version: v1
  deprecated: 'true'
- version: v1
  deprecated: 'true'
- version: v2
  deprecated: 'false'

感谢您的帮助。

我相信你可以这样做:

def myappMap = yaml.load(myappFile.text)
if (!myappMap.contexts?.find { it.version == 'v2' }) {
    if (!myappMap.contexts) {
        myappMap.contexts = []
    }
    myappMap.contexts << [version: 'v2', deprecated: "false"]
    new File(fileName).withWriter {
        yaml.dump(myappMap, it)
    }
}