简体   繁体   English

使用 Java 从 YAML 文件中删除 Key:Value 属性

[英]Remove Key:Value property from YAML File using Java

Goal : I have a YAML file that needed to remove some key: value properties from.目标:我有一个 YAML 文件,需要从中删除一些 key: value 属性。 Then I want to create a new YAML file with doesn't exist removed key: value properties.然后我想创建一个新的 YAML 文件,其中不存在已删除的键:值属性。 The required key should be removed from the whole YAML file.应从整个 YAML 文件中删除所需的密钥。

Expected Result : Should Iterate through the YAML File and identify the required key: value to be removed and then remove and continue searching for such key: value properties.预期结果:应该遍历 YAML 文件并确定要删除的所需键:值,然后删除并继续搜索此类键:值属性。

Actual Result : Even though iterating through the YAML file desired key: value property won't' remove from the YAML File.实际结果:即使遍历 YAML 文件所需的 key: value 属性也不会从 YAML 文件中删除。

Errors : No Compile or Runtime errors, there seems to be a logical error.错误:没有编译或运行时错误,似乎存在逻辑错误。

What I have tried :我尝试过的

  • Use Jackson ObjectMapper to read the YAML file.使用 Jackson ObjectMapper 读取 YAML 文件。
  • Put all the properties into LinkedHashMap such that I can preserve the order and I can remove items将所有属性放入 LinkedHashMap 以便我可以保留订单并删除项目

My Logic : Implement two methods我的逻辑:实现两种方法

  • one is to iterate the LinkedHashMap and ArrayList object一种是迭代LinkedHashMap和ArrayList对象
  • another one it to check whether a specific key is removable另一个检查特定密钥是否可移动
  • If a removable key is found and remove from the LinkedHashMap and continues searching the same key in other items in the YAML file.如果找到可移动键并从 LinkedHashMap 中删除并继续在 YAML 文件中的其他项目中搜索相同的键。

for example I want to remove "originalRef": "Conditions" (the key is String data type) from the YAML file.例如我想从 YAML 文件中删除"originalRef": "Conditions" (键是字符串数据类型)。 This key can contain in a LinkedHashMap.该键可以包含在 LinkedHashMap 中。 Also, There could be ArrayLists which contains multiple LinkedHashMaps.此外,可能有包含多个 LinkedHashMap 的 ArrayLists。

Code : Below are the YAML file I'm using for these purpose.代码:以下是我用于这些目的的 YAML 文件。 api-test.yml this only contains a small portion of my big YAML file. api-test.yml这仅包含我的大 YAML 文件的一小部分。

---
swagger: '2.0'
info:
  description: |-
    Planner application is a proposal system enables user to create, manage plan .  
    It 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
  - name: Conditions Status APIs
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'
            originalRef: 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'
            originalRef: Conditions
        - name: entityId
          in: path
          description: Entity ID
          required: true
          type: string
      responses:
        '200':
          description: OK
          schema:
            $ref: '#/definitions/Conditions'
            originalRef: Conditions
      deprecated: false


below is the Java class for parsing above the YAML file and doing the needful.下面是用于解析 YAML 文件并执行所需操作的 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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

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

@Service
public class YamlProcessorGeneric {

    Logger logger = LoggerFactory.getLogger(YamlProcessorGeneric.class);

    public YamlProcessorGeneric() 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-test.yaml"),
                new TypeReference<Map<String, Object>>() {
                });

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

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

    private void extractLinkedHashMap(final Map<String,Object> itemMap) {
        itemMap.entrySet().forEach(k -> {

            // if k is a linkedhashmap and again iterate through
            if(k.getValue() instanceof LinkedHashMap) {
                extractLinkedHashMap((Map<String, Object>) k.getValue());
            }

            // if k is an arraylist then iterate through to till I find a linkedhashmap
            // so that I can remove an item.
            if(k.getValue() instanceof ArrayList) {
                ((ArrayList<?>) k.getValue()).forEach(singleItem -> {
                   if(!(singleItem instanceof String)) {
                       extractLinkedHashMap((Map<String, Object>) singleItem);
                   }
                });
            }

            // check for a specific key , if found remove from the linkedhashmap
            // but this doesn't work
            if(isRemovable(k.getKey())) {
                itemMap.remove(k);
            }

        });
    }

    private boolean isRemovable(final String key) {
        // eg:- I want to remove key with originalRef
        String removableString = "originalRef";
        return key.equals(removableString);
    }
}

for the demonstration process I will attach a screenshot when I was debugging the application.对于演示过程,我将在调试应用程序时附上屏幕截图。 All the values of itemMap . itemMap所有值。

在此处输入图片说明

I'm currently out of options trying out.我目前没有选择尝试。 Please Can anyone give me direction where I'm doing wrong here.请任何人都可以给我指示我在这里做错的地方。 Any help would be very much appreciated.任何帮助将不胜感激。 Good day!再会!

If still relevant or somebody want to know, how to do.如果仍然相关或有人想知道,该怎么办。

First, lets say we have Yaml object:首先,假设我们有 Yaml 对象:

public class Project  {

    private String name;
    private String description;
    private long lastUpdate;

    public Project() {
    }

    // getter, setter
}

now we want to remove lastUpdate field from data.现在我们要从数据中删除lastUpdate字段。

  1. Remove getter from Project (update UI to not use getter of property)Project删除 getter(更新 UI 以不使用属性的 getter)
  2. Start project启动项目
  3. Save the Yaml object again -> lastUpdate property from file is gone再次保存 Yaml 对象 -> 文件中的lastUpdate属性消失了
  4. Now you can remove lastUpdate and setter from Project现在您可以从Project删除lastUpdate和 setter

If the project is already in use by many people:如果该项目已经被很多人使用:

  1. Remove getter from Project and clean UIProject删除 getter 并清理 UI
  2. After some time in use can remove the property from file (if all users have ones saved new Yaml object)使用一段时间后可以从文件中删除该属性(如果所有用户都保存了新的 Yaml 对象)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM