【问题标题】:Remove Key:Value property from YAML File using Java使用 Java 从 YAML 文件中删除 Key:Value 属性
【发布时间】:2020-09-14 13:41:48
【问题描述】:

目标:我有一个 YAML 文件,需要从中删除一些 key: value 属性。然后我想创建一个新的 YAML 文件,其中不存在已删除的键:值属性。应从整个 YAML 文件中删除所需的密钥。

预期结果:应该遍历 YAML 文件并确定要删除的所需键:值,然后删除并继续搜索此类键:值属性。

实际结果:即使遍历 YAML 文件所需的 key: value 属性也不会从 YAML 文件中删除。

错误:没有编译或运行时错误,似乎存在逻辑错误。

我的尝试

  • 使用 Jackson ObjectMapper 读取 YAML 文件。
  • 将所有属性放入 LinkedHashMap 中,这样我就可以保留订单并删除项目

我的逻辑:实现两种方法

  • 一种是迭代LinkedHashMap和ArrayList对象
  • 另一个检查特定键是否可移动
  • 如果找到一个可移除的键并从 LinkedHashMap 中移除,并继续在 YAML 文件的其他项中搜索相同的键。

例如,我想从 YAML 文件中删除 "originalRef": "Conditions"(键是字符串数据类型)。该键可以包含在 LinkedHashMap 中。此外,可能存在包含多个 LinkedHashMaps 的 ArrayLists。

代码:下面是我用于这些目的的 YAML 文件。 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


下面是用于解析 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);
    }
}

对于演示过程,我将在调试应用程序时附上屏幕截图。 itemMap 的所有值。

我目前没有尝试的选项。请任何人都可以给我指示我在这里做错的地方。 任何帮助将不胜感激。 美好的一天!

【问题讨论】:

    标签: java generics yaml linkedhashmap


    【解决方案1】:

    如果仍然相关或有人想知道,该怎么做。

    首先,假设我们有 Yaml 对象:

    public class Project  {
    
        private String name;
        private String description;
        private long lastUpdate;
    
        public Project() {
        }
    
        // getter, setter
    }
    

    现在我们要从数据中删除 lastUpdate 字段。

    1. Project 中移除 getter(更新 UI 以不使用属性的 getter)
    2. 开始项目
    3. 再次保存 Yaml 对象 -> 文件中的 lastUpdate 属性消失了
    4. 现在您可以从Project 中删除lastUpdate 和setter

    如果项目已经被很多人使用:

    1. Project 中移除 getter 并清理 UI
    2. 使用一段时间后可以从文件中删除属性(如果所有用户都有保存的新 Yaml 对象)

    【讨论】:

      猜你喜欢
      • 2018-07-21
      • 2020-12-30
      • 2013-02-20
      • 1970-01-01
      • 1970-01-01
      • 2017-04-18
      • 2012-05-31
      • 2013-02-20
      • 1970-01-01
      相关资源
      最近更新 更多