【问题标题】:Cannot remove specific key: value from YAML file无法删除特定键:YAML 文件中的值
【发布时间】:2020-12-28 16:24:07
【问题描述】:

目标:我想从 YAML 文件中删除特定键及其关联值。

预期结果:orginalRef 键及其值应从 YAML 文件中删除,并应生成新的 YAML 文件。

实际结果:responses 属性下的orginalRef 值不会被删除。

错误消息:没有错误消息。

我尝试过什么:我有一个大摇大摆的 YAML 文件,我只是将它加载到 Jackson ObjectMapper 并尝试从该 YAML 文件中删除一些键。然后使用我所做的更改生成一个新的 YAML 文件。

代码: 下面是我巨大的 YAML 文件的一部分。它的名字是api.yaml

---
swagger: "2.0"
info:
  description: "Planner application is a proposal system enables user to create, manage\
    \ plan .  \nIt also enables network user to publish plan "
  version: "1.0"
  title: "Planner API"
  contact:
    name: "API team"
    email: "apiteam@test.com"
  license:
    name: "Copyright © 2020 test
host: "aos-dev.test.com"
basePath: "/unifiedplanner"
tags:
- name: "Additional Fee APIs"
  description: "Additional Fee Controller"
- name: "Condition APIs"
  description: "Condition Controller"
paths:
  /v1/{apiKey}/entity/{entityId}:
    post:
      tags:
      - "Condition APIs"
      summary: "Save New Conditions Entity"
      operationId: "saveNewConditions"
      consumes:
      - "application/json"
      produces:
      - "application/json"
      parameters:
      - name: "Authorization"
        in: "header"
        description: "Authorization"
        required: true
        type: "string"
      - name: "apiKey"
        in: "path"
        description: "API Key"
        required: true
        type: "string"
      - in: "body"
        name: "conditions"
        description: "Conditions Entity that needs to be saved"
        required: true
        schema:
          $ref: "#/definitions/Conditions"
      - name: "entityId"
        in: "path"
        description: "Entity ID"
        required: true
        type: "string"
      responses:
        "200":
          description: "OK"
          schema:
            $ref: "#/definitions/Conditions"
            originalRef: "Conditions"
      deprecated: false
    put:
      tags:
      - "Condition APIs"
      summary: "Modify / Overwrite existing Conditions Entity"
      operationId: "modifyConditions"
      consumes:
      - "application/json"
      produces:
      - "application/json"
      parameters:
      - name: "Authorization"
        in: "header"
        description: "Authorization"
        required: true
        type: "string"
      - name: "apiKey"
        in: "path"
        description: "API Key"
        required: true
        type: "string"
      - in: "body"
        name: "conditions"
        description: "Conditions Entity that needs to be updated"
        required: true
        schema:
          $ref: "#/definitions/Conditions"
      - name: "entityId"
        in: "path"
        description: "Entity ID"
        required: true
        type: "string"
      responses:
        "200":
          description: "OK"
          schema:
            $ref: "#/definitions/Conditions"
            originalRef: "Conditions"
      deprecated: false
definitions:
  AbstractCondition:
    type: "object"
    properties:
      externalTrafficSystem:
        $ref: "#/definitions/ExternalTrafficSystem"
        originalRef: "ExternalTrafficSystem"
      id:
        type: "string"
      version:
        type: "integer"
        format: "int64"
    title: "AbstractCondition"

如您所见,我只想从上述 YAML 文件中的 responses 属性中删除 originalRef 键和它的值。

下面是我的 YamlProcessor.java 类,它完成了所有必要的事情。

package com.aos.tools.aostool.yaml;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Stream;

@Service
public class YamlProcessor {

    public YamlProcessor() throws IOException {
        process();
    }

    public void process() throws IOException {
        final ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());

        final Map<String, Object> api = objectMapper.readValue(new File("api.yaml"),
                new TypeReference<Map<String, Object>>() {
                });

        final Map<String, Object> path = (Map<String, Object>) api.get("paths");
        processPath(path);

        // write YAML file
        final Date date = Calendar.getInstance().getTime();
        objectMapper.writeValue(new File(date.toString() + "api-updated.yaml"), api);
    }

    private void processPath(final Map<String, Object> paths) {
        paths.entrySet().forEach(path -> {
            if (null != path) {
                final Map<String, Object> level1Child = (Map<String, Object>) path.getValue();
                if (null != level1Child) {
                    level1Child.entrySet().forEach(method -> {
                        final Map<String, Object> methodValues = (Map<String, Object>) method.getValue();
                        methodValues.entrySet().forEach(methodValue -> {
                            if (null != methodValue && methodValue.getKey().equals("parameters")) {
                                final List<Object> paramValue = (List<Object>) methodValue.getValue();
                                paramValue.forEach(paramValueChild -> {
                                    if (null != paramValueChild) {
                                        final Map<String, Object> paramMap = (HashMap<String, Object>) paramValueChild;
                                        paramMap.entrySet().forEach(k -> {
                                            if (k.getKey().contains("schema")) {
                                                final Map<String, Object> schema = (HashMap<String, Object>) k.getValue();
                                                // this line works fine , this will remove all the originalRef keys under parameters property
                                                schema.remove("originalRef"); 
                                            }
                                        });
                                    }
                                });
                            }

                            // this is where I'm currently getting stucked.
                            if (null != methodValue && methodValue.getKey().equals("responses")) {
                                Map<String,Object> value = (HashMap<String,Object>) methodValue.getValue();
                                if(value.containsKey("200")) {
                                    value.entrySet().forEach(k -> {
                                        if(k.getKey().contains("schema")) {
                                            Map<String,Object> responseSchema = (HashMap<String,Object>)k.getValue();
                                            responseSchema.remove("originalRef");
                                        }
                                    });
                                }
                            }
                        });
                    });
                }
            }
        });
    }
}

当我运行应用程序时,它运行良好,没有任何错误。同时生成新的 YAML 文件。 但在新的 YAML 文件中,responses 属性下仍然包含 originlaRef 键。 任何人都在这里指导我做错了什么。 任何帮助将不胜感激。 干杯!美好的一天!

【问题讨论】:

    标签: java hashmap yaml


    【解决方案1】:

    您正在迭代 value 的内容,而不是 value.200

     if(value.containsKey("200")) {
              value.entrySet().forEach(k -> {
    

    应该是

     if(value.containsKey("200")) {
              value.get("200").entrySet().forEach(k -> {
    

    在任何情况下,您都可以将日志语句放入循环中以调试此类事情。

    【讨论】:

    • value.get("200").entrySet() , value.get() 方法下不存在这个。
    • 所以你从你的代码中说,HashMap没有get(key)方法?
    • 是的,当我尝试从 value.get() 方法访问 .entrySet() 方法时,它不允许我。
    • 你必须投。
    【解决方案2】:

    我终于可以通过我的代码进行实验来获得所需的输出。

    下面是我的工作解决方案。

    if(value.containsKey("200")) {
        value.entrySet().forEach(k -> {
            Map<String,Object> responseSchema = (HashMap<String,Object>) k.getValue();
            responseSchema.entrySet().forEach(a -> {
                if(a.getKey().contains("schema")) {
                    Map<String,Object> reSchema = (HashMap<String,Object>)a.getValue();
                    reSchema.entrySet().forEach(c -> {
                        if(c.getKey().contains("items")) {
                            Map<String,Object> innerSchema = (HashMap<String,Object>) c.getValue();
                            innerSchema.remove("originalRef");
                        }
                    });
                }
            });
        });
    }
    

    【讨论】:

      猜你喜欢
      • 2021-09-29
      • 2022-07-07
      • 1970-01-01
      • 1970-01-01
      • 2020-01-01
      • 2016-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多