我有一些YAML文件包含很多配置,但我只需要其中的一个标记(mytag)。
component:
field1:
- name: nnn1
field2:
- name: mmm1
mytag:
description: hello
mycomponents:
- propertyA: aaa
propertyB: bbb
theirtag:
bbb: 111
comps:
- propA: aaa
prop: bbb
我需要加载:
class MyClass {
String description;
List<MyComponent> mycomponents:
}
如何使用SnakeYaml做到这一点?我没能很快找到任何有用的例子。
跟进:如果我的标签嵌套得更深,该怎么办:(boo/mytag)
boo:
mytag:
description: hello
mycomponents:
- propertyA: aaa
propertyB: bbb
谢谢
这不是小事。虽然使用自定义构造函数可能是可行的,但对于这种情况,它们的接口很难处理,我不确定如何处理。
相反,您可以覆盖默认的解析器行为,只需丢弃mytag
键周围的任何事件,这样解析器发出的事件流只包含mytag
键值内的事件。下面是一个简单的工作示例:
package droggeljug;
import org.yaml.snakeyaml.parser.ParserImpl;
import org.yaml.snakeyaml.events.*;
import org.yaml.snakeyaml.composer.Composer;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.reader.StreamReader;
import java.io.*;
import java.util.List;
public class Main {
public static class MyParser extends ParserImpl {
private final String containingKey;
private int depth = -1;
private boolean checked = false;
public MyParser(StreamReader reader, boolean emitComments, String containingKey) {
super(reader, emitComments);
this.containingKey = containingKey;
}
@Override
public Event peekEvent() {
if (checked) return super.peekEvent();
Event e;
while (true) {
boolean seenContainingKey = false;
e = super.peekEvent();
switch (e.getEventId()) {
case StreamStart:
case DocumentStart:
case Comment:
case StreamEnd:
case DocumentEnd:
return e;
case Scalar:
if (depth == -1) {
if (containingKey.equals(((ScalarEvent)e).getValue())) {
seenContainingKey = true;
break;
}
}
case Alias:
break;
case MappingStart:
case SequenceStart:
if (depth > -1) {
depth++;
}
break;
case MappingEnd:
case SequenceEnd:
if (depth > -1) {
depth--;
}
break;
}
if (seenContainingKey) {
depth = 0;
} else if (depth > -1) break;
checked = true; super.getEvent(); checked = false; // discard
}
if (depth == 0) depth = -1;
checked = true;
return e;
}
public Event getEvent() {
Event ret = super.getEvent();
checked = false;
return ret;
}
}
public static class MyYaml extends Yaml {
private Object loadContainedFromReader(StreamReader sreader, Class<?> type, String containingKey) {
Composer composer = new Composer(new MyParser(sreader,
loadingConfig.isProcessComments(), containingKey), resolver, loadingConfig);
constructor.setComposer(composer);
return constructor.getSingleData(type);
}
@SuppressWarnings("unchecked")
public <T> T loadContainedAs(Reader io, Class<T> type, String containingKey) {
return (T) loadContainedFromReader(new StreamReader(io), type, containingKey);
}
}
public static class MyClass {
public static class MyComponent {
public String propertyA, propertyB;
}
public String description;
public List<MyComponent> mycomponents;
}
private static final String input =
"component:\n" +
"field1:\n" +
" - name: nnn1\n" +
"field2:\n" +
" - name: mmm1\n" +
"mytag:\n" +
" description: hello\n" +
" mycomponents:\n" +
" - propertyA: aaa\n" +
" propertyB: bbb\n" +
"theirtag:\n" +
" bbb: 111\n" +
" comps:\n" +
" - propA: aaa\n" +
" prop: bbb\n";
public static void main(String args[]) {
MyYaml yaml = new MyYaml();
MyClass data = yaml.loadContainedAs(new StringReader(input), MyClass.class, "mytag");
System.out.println("description = " + data.description);
for (MyClass.MyComponent c : data.mycomponents) {
System.out.println("component: (" + c.propertyA + ", " + c.propertyB + ")");
}
}
}
过滤代码不完全正确,例如,如果mytag
是某个值或序列项,则会失败。您需要跟踪解析器状态,以确保当前标量是映射键。我没有实现它,因为代码已经足够长了。
我试图创建一个随机数生成器程序,跟踪玩家的胜利,损失,获胜百分比和总奖金。该程序的逻辑是,玩家每节获得3次机会,计算机生成一个随机数,玩家需要猜测或者更确切地说应该匹配。 我试过用如果 如果您对此有任何意见,我们将不胜感激。 游戏类别:
有时,项目中的许多广为流传的惯例和协定变得非常重要,你需要记录下来。为了保证这种文档的正统性,要清楚的表明这些内容基于邮件列表的讨论,并已经形成协定开始生效。随着你的编写,应当引用邮件列表归档中的相关讨论,对于任何不能确定的要点,要重新询问并确认。文档中不应当包含任何出其不意的东西:它不应当是协议的来源,而只是对于协议的描述。当然,如果它足够成功,人们会开始引用它来作为自己权利的来源,但是这只是说
我想把一个字符串拆分成单个单词。如果字符串是: 我想存储为: 如果我使用则变成。我该怎么做呢
我使用php删除文件夹包含删除的帖子的图像。我正在使用下面的代码,我在网上找到的,做得很好。 我想知道当文件夹中有其他文件夹时,如何仅删除文件夹中的特定文件夹。 当我使用下面的代码时,如何做到这一点?使用:/dev/images/norman/8-
问题内容: 我想知道是否有任何方法可以导入包的全部内容,从而不必在调用包名称之前对包中的内容添加前缀? 例如,有一种方法可以替代此方法: 有了这个: 问题答案: Go编程语言规范 进口报关单 如果出现一个明显的句点(。)而不是名称,则在该软件包的package块中声明的所有软件包导出标识符都将在导入源文件的file块中声明,并且必须在不使用限定符的情况下进行访问。 例如, 游乐场:https :
我对log4j2比较陌生。当前,我有以下配置文件: 如果我通过静态记录器在这两个类Consoleain和ClientMain中记录一些东西 而且 他们总是使用根记录器的附加器和级别。如果根记录器的级别是“错误”,那么它永远不会显示任何调试级别的日志输出,即使单个记录器的级别是调试。而且,它总是追加到根记录器中指定的日志文件,而不是类的记录器中指定的日志文件。 所以,根记录器似乎以某种方式覆盖了所有