无法从 YAML 文件中删除特定键:值
Cannot remove specific key: value from YAML file
目标:我想从 YAML 文件中删除特定键及其关联值。
预期结果:orginalRef
键及其值应从 YAML 文件中删除并生成新的 YAML 文件。
实际结果:responses
属性 下的 orginalRef
值未删除。
错误信息: 没有错误信息。
我尝试了什么:我有一个 swagger 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 class,它完成了所有必要的事情。
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 文件中,响应 属性 下仍然包含 originlaRef 键。
任何人都在这里指导我做错了什么。
任何帮助将不胜感激。
干杯!美好的一天!
你迭代的是value的内容,不是value.200
if(value.containsKey("200")) {
value.entrySet().forEach(k -> {
应该是
if(value.containsKey("200")) {
value.get("200").entrySet().forEach(k -> {
在任何情况下,您都可以将日志语句放入循环中以调试此类内容。
最后,我能够通过试验我的代码获得所需的输出。
下面是适合我的解决方案。
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");
}
});
}
});
});
}
目标:我想从 YAML 文件中删除特定键及其关联值。
预期结果:orginalRef
键及其值应从 YAML 文件中删除并生成新的 YAML 文件。
实际结果:responses
属性 下的 orginalRef
值未删除。
错误信息: 没有错误信息。
我尝试了什么:我有一个 swagger 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 class,它完成了所有必要的事情。
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 文件中,响应 属性 下仍然包含 originlaRef 键。 任何人都在这里指导我做错了什么。 任何帮助将不胜感激。 干杯!美好的一天!
你迭代的是value的内容,不是value.200
if(value.containsKey("200")) {
value.entrySet().forEach(k -> {
应该是
if(value.containsKey("200")) {
value.get("200").entrySet().forEach(k -> {
在任何情况下,您都可以将日志语句放入循环中以调试此类内容。
最后,我能够通过试验我的代码获得所需的输出。
下面是适合我的解决方案。
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");
}
});
}
});
});
}