在保留注释的同时修改java中的YAML
如何修改现有YAML并在其中保留注释。 有没有这样的Java解析器? 例如,如果我有以下YAML:在保留注释的同时修改java中的YAML,java,yaml,snakeyaml,Java,Yaml,Snakeyaml,如何修改现有YAML并在其中保留注释。 有没有这样的Java解析器? 例如,如果我有以下YAML: #This is a test YAML name: abcd age: 23 #Test YAML ends here. 是否有一种方法可以使用java解析器编辑此Yaml并保留注释 在撰写本文时,还没有针对Java的往返YAML解析器。有一个著名的项目,它不保留注释(参见),还有一个新的项目,名为,我对它知之甚少;但这绝对不是往返 理论上,您可以使用SnakeYaml的Yaml.pars
#This is a test YAML
name: abcd
age: 23
#Test YAML ends here.
是否有一种方法可以使用java解析器编辑此Yaml并保留注释 在撰写本文时,还没有针对Java的往返YAML解析器。有一个著名的项目,它不保留注释(参见),还有一个新的项目,名为,我对它知之甚少;但这绝对不是往返 理论上,您可以使用SnakeYaml的
Yaml.parse
,然后迭代事件。每个事件都有一个开始和结束标记,给出事件的开始和结束行及列。这使得将事件映射回源代码并发现源代码中未解析为事件的部分(可能是注释)成为可能。有了这个映射,您现在可以修改事件列表并将其写回。最后,第二次阅读结果,发现事件之间的差距,在原始YAML中有注释,但在修改后的YAML中没有,然后重新插入这些注释,为您提供带有修改和注释的最终YAML
当然,这是非常复杂的。我不会建议您这样做,除非您a)对YAML的结构有深入的了解,或者愿意学习它,b)您的用例证明了这么多工作的合理性。我编写了一个groovy脚本来解决这个问题。Java版本非常相似:
def key = "name"
def value = "efgh"
def yamlFile = new File("file.yaml")
def yamlFileLines = new StringBuilder()
def foundKey = false
yamlFile.text.eachLine { line ->
if (!foundKey && line.contains("$key:")) {
line = line.replaceAll(/$key:.*/, "$key: $value")
foundKey = true
}
yamlFileLines.append("$line\n")
}
if (foundKey) {
yamlFile.text = yamlFileLines.toString()
} else {
throw new StopExecutionException("Could not find key '$key' in file ${yamlFile.getAbsolutePath()}")
}
如果使用snakeyaml,则应修改ScannerImpl文件 注意:以文本形式阅读内嵌注释
private Token scanPlain() {
StringBuilder chunks = new StringBuilder();
Mark startMark = reader.getMark();
Mark endMark = startMark;
int indent = this.indent + 1;
String spaces = "";
while (true) {
int c;
int length = 0;
// A comment indicates the end of the scalar.
// read the in-line comment as text
// if (reader.peek() == '#' && ) {
// break;
// }
while (true) {
c = reader.peek(length);
if (Constant.NULL_BL_T_LINEBR.has(c)
|| (c == ':' && Constant.NULL_BL_T_LINEBR.has(reader.peek(length + 1), flowLevel != 0 ? ",[]{}":""))
|| (this.flowLevel != 0 && ",?[]{}".indexOf(c) != -1)) {
break;
}
length++;
}
if (length == 0) {
break;
}
this.allowSimpleKey = false;
chunks.append(spaces);
chunks.append(reader.prefixForward(length));
endMark = reader.getMark();
spaces = scanPlainSpaces();
// System.out.printf("spaces[%s]\n", spaces);
if (spaces.length() == 0
// read the in-line comment as text
// || reader.peek() == '#'
|| (this.flowLevel == 0 && this.reader.getColumn() < indent)) {
break;
}
}
return new ScalarToken(chunks.toString(), startMark, endMark, true);
}
private-Token-scanplane(){
StringBuilder chunks=新的StringBuilder();
markstartmark=reader.getMark();
标记endMark=开始标记;
int indent=this.indent+1;
字符串空格=”;
while(true){
INTC;
整数长度=0;
//注释表示标量的结束。
//以文本形式阅读内嵌注释
//if(reader.peek(){
//中断;
// }
while(true){
c=读卡器.窥视(长度);
if(常数为空)br.has(c)
||(c==':'&&Constant.NULL_BL_T_LINEBR.has(reader.peek(长度+1),flowLevel!=0?,[]{}:“)
||(this.flowLevel!=0&&“,?[{}”.indexOf(c)!=-1)){
打破
}
长度++;
}
如果(长度==0){
打破
}
this.allowSimpleKey=false;
chunks.append(空格);
append(reader.prefixForward(length));
endMark=reader.getMark();
空格=扫描平面空格();
//System.out.printf(“空格[%s]\n”,空格);
if(spaces.length()==0
//以文本形式阅读内嵌注释
//| | reader.peek()=='#'
||(this.flowLevel==0&&this.reader.getColumn()
你试过蛇山药吗?默认情况下不支持吗?