【发布时间】: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