你能帮我读一下这个 YAML 文件吗?
Can you help me to read this YAML file?
我是 YAML 新手。我尝试按照教程 (https://www.java-success.com/yaml-java-using-snakeyaml-library-tutorial/) 进行操作,但它不完整。到目前为止,我的 YAML 文件如下所示:
tests:
- class: tests.layers.DeleteCustomLayerTest
param: layer
value: Test Layer
- class: tests.routes.ViewRoutesTest
param: project
value: SNS Project Test
我已将 snakeyaml 添加到我的 pom.xml 文件中:
<dependencies>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.21</version>
</dependency>
我已将 snakeyaml-1.21.jar 添加到我的 libs 文件夹中。
我已经为名为 YamlTestDataFile 的文件创建了一个定义:
package otherObjects;
import java.util.Map;
public class YamlTestDataFile {
private Map<String, String> tests;
public Map<String, String> getTests() {
return tests;
}
public void setTests(Map<String, String> tests) {
this.tests = tests;
}
public Map<String, String> getTests(Map<String, String> tests) {
this.tests = tests;
return tests;
}
}
最后,读取文件的实用程序:
package utils;
import java.io.InputStream;
import org.yaml.snakeyaml.Yaml;
import otherObjects.YamlTestDataFile;
public class ReadYamlTestData {
public static void main(String[] args) {
YamlTestDataFile testData = null;
Yaml yaml = new Yaml();
try(InputStream in = ClassLoader.getSystemResourceAsStream("testData.yml")) {
testData = yaml.loadAs(in, YamlTestDataFile.class);
} catch(Exception ex) {
ex.printStackTrace();
}
String test = testData.getTests().get("class");
System.out.println("test=" + test);
}
}
当我 运行 它时,出现以下错误:
Cannot create property=tests for JavaBean=otherObjects.YamlTestDataFile@5fdef03a
in 'reader', line 1, column 1:
tests:
^
No suitable constructor with 2 arguments found for interface java.util.Map
in 'reader', line 2, column 1:
- class: tests.layers.DeleteCust ...
恐怕我不知道发生了什么,也找不到任何像样的教程来解释得更好。
根据flyx的回复,我在这方面有了一些进展。
首先,我更改了 YAML 文件,因此它没有使用单词 class:
tests:
- className: tests.layers.DeleteCustomLayerTest
param: layer
value: Test Layer
- className: tests.routes.ViewRoutesTest
param: project
value: SNS Project Test
我的 YAML 文件定义如下所示:
package otherObjects;
import java.util.List;
public class YamlTestDataFile {
/* public, no-argument constructor */
public YamlTestDataFile() {
}
public static final class Test {
private String className;
public String param;
public String value;
public String getClassName() { return className; }
public void setClassName(final String value) { className = value; }
public String getParam() { return param; }
public void setParam(final String value) { param = value; }
public String getValue() { return value; }
public void setValue(final String string) { param = string; }
}
private List<Test> tests;
public List<Test> getTests() {
return tests;
}
public void setTests(List<Test> tests) {
this.tests = tests;
}
}
和我的 reader:
package utils;
import java.io.InputStream;
import java.util.List;
import org.yaml.snakeyaml.TypeDescription;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import otherObjects.YamlTestDataFile;
import otherObjects.YamlTestDataFile.Test;
public class ReadYamlTestData {
public static void main(String[] args) {
Constructor constructor = new Constructor(YamlTestDataFile.class);
TypeDescription dataDesc = new TypeDescription(YamlTestDataFile.class);
dataDesc.putListPropertyType("tests", YamlTestDataFile.Test.class);
constructor.addTypeDescription(dataDesc);
Yaml yaml = new Yaml(constructor);
InputStream in = ClassLoader.getSystemResourceAsStream("testData.yml");
YamlTestDataFile testData = null;
try {
testData = yaml.loadAs(in, YamlTestDataFile.class);
}catch(Exception e) {
System.err.println("Exception:" + e.getMessage());
e.printStackTrace();
}
List<Test> tests=testData.getTests();
for (int x=0; x<tests.size(); x++)
System.out.println(tests.get(x).getClassName() + ", " + tests.get(x).getParam() + ", " + tests.get(x).getValue());
}
}
输出正是我要找的:
tests.layers.DeleteCustomLayerTest, layer, Test Layer
tests.routes.ViewRoutesTest, project, SNS Project Test
您的代码中定义的 class 与 YAML 数据的结构不匹配。
在您的 YAML 文件中,您的根是一个包含一个键 tests
的映射。此键的值是一系列映射。您将此构造映射到一个 class,它有一个字段 tests
,它是一个 Map<String, String>
。因此,您正在尝试从 YAML 序列构建 Java Map
。 SnakeYaml 理所当然地抱怨它不能那样做。
你的 YAML 结构看起来像你想做这样的事情:
public class YamlTestDataFile {
public static final class Test {
private String className;
public String param;
public String value;
public String getClass() { return className; }
public void setClass(final String value) { className = value; }
}
private List<Test> tests;
public List<Test> getTests() {
return tests;
}
public void setTests(List<Test> tests) {
this.tests = tests;
}
}
请注意 class
是 Java 中的关键字,因此我们需要 getter 和 setter 来加载该值。
类型擦除阻止 SnakeYaml 查看 tests
列表的通用参数是什么。因此,我们需要告诉它这是一个Test
的列表。让我们适当修改加载代码:
Constructor constructor = new Constructor(YamlTestDataFile.class);
TypeDescription dataDesc = new TypeDescription(YamlTestDataFile.class);
dataDesc.putListPropertyType("tests", YamlTestDataFile.Test.class);
constructor.addTypeDescription(dataDesc);
Yaml yaml = new Yaml(constructor);
InputStream in = ClassLoader.getSystemResourceAsStream("testData.yml");
testData = yaml.loadAs(in, YamlTestDataFile.class);
提示:代码未经测试。
我是 YAML 新手。我尝试按照教程 (https://www.java-success.com/yaml-java-using-snakeyaml-library-tutorial/) 进行操作,但它不完整。到目前为止,我的 YAML 文件如下所示:
tests:
- class: tests.layers.DeleteCustomLayerTest
param: layer
value: Test Layer
- class: tests.routes.ViewRoutesTest
param: project
value: SNS Project Test
我已将 snakeyaml 添加到我的 pom.xml 文件中:
<dependencies>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.21</version>
</dependency>
我已将 snakeyaml-1.21.jar 添加到我的 libs 文件夹中。
我已经为名为 YamlTestDataFile 的文件创建了一个定义:
package otherObjects;
import java.util.Map;
public class YamlTestDataFile {
private Map<String, String> tests;
public Map<String, String> getTests() {
return tests;
}
public void setTests(Map<String, String> tests) {
this.tests = tests;
}
public Map<String, String> getTests(Map<String, String> tests) {
this.tests = tests;
return tests;
}
}
最后,读取文件的实用程序:
package utils;
import java.io.InputStream;
import org.yaml.snakeyaml.Yaml;
import otherObjects.YamlTestDataFile;
public class ReadYamlTestData {
public static void main(String[] args) {
YamlTestDataFile testData = null;
Yaml yaml = new Yaml();
try(InputStream in = ClassLoader.getSystemResourceAsStream("testData.yml")) {
testData = yaml.loadAs(in, YamlTestDataFile.class);
} catch(Exception ex) {
ex.printStackTrace();
}
String test = testData.getTests().get("class");
System.out.println("test=" + test);
}
}
当我 运行 它时,出现以下错误:
Cannot create property=tests for JavaBean=otherObjects.YamlTestDataFile@5fdef03a
in 'reader', line 1, column 1:
tests:
^
No suitable constructor with 2 arguments found for interface java.util.Map
in 'reader', line 2, column 1:
- class: tests.layers.DeleteCust ...
恐怕我不知道发生了什么,也找不到任何像样的教程来解释得更好。
根据flyx的回复,我在这方面有了一些进展。
首先,我更改了 YAML 文件,因此它没有使用单词 class:
tests:
- className: tests.layers.DeleteCustomLayerTest
param: layer
value: Test Layer
- className: tests.routes.ViewRoutesTest
param: project
value: SNS Project Test
我的 YAML 文件定义如下所示:
package otherObjects;
import java.util.List;
public class YamlTestDataFile {
/* public, no-argument constructor */
public YamlTestDataFile() {
}
public static final class Test {
private String className;
public String param;
public String value;
public String getClassName() { return className; }
public void setClassName(final String value) { className = value; }
public String getParam() { return param; }
public void setParam(final String value) { param = value; }
public String getValue() { return value; }
public void setValue(final String string) { param = string; }
}
private List<Test> tests;
public List<Test> getTests() {
return tests;
}
public void setTests(List<Test> tests) {
this.tests = tests;
}
}
和我的 reader:
package utils;
import java.io.InputStream;
import java.util.List;
import org.yaml.snakeyaml.TypeDescription;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import otherObjects.YamlTestDataFile;
import otherObjects.YamlTestDataFile.Test;
public class ReadYamlTestData {
public static void main(String[] args) {
Constructor constructor = new Constructor(YamlTestDataFile.class);
TypeDescription dataDesc = new TypeDescription(YamlTestDataFile.class);
dataDesc.putListPropertyType("tests", YamlTestDataFile.Test.class);
constructor.addTypeDescription(dataDesc);
Yaml yaml = new Yaml(constructor);
InputStream in = ClassLoader.getSystemResourceAsStream("testData.yml");
YamlTestDataFile testData = null;
try {
testData = yaml.loadAs(in, YamlTestDataFile.class);
}catch(Exception e) {
System.err.println("Exception:" + e.getMessage());
e.printStackTrace();
}
List<Test> tests=testData.getTests();
for (int x=0; x<tests.size(); x++)
System.out.println(tests.get(x).getClassName() + ", " + tests.get(x).getParam() + ", " + tests.get(x).getValue());
}
}
输出正是我要找的:
tests.layers.DeleteCustomLayerTest, layer, Test Layer
tests.routes.ViewRoutesTest, project, SNS Project Test
您的代码中定义的 class 与 YAML 数据的结构不匹配。
在您的 YAML 文件中,您的根是一个包含一个键 tests
的映射。此键的值是一系列映射。您将此构造映射到一个 class,它有一个字段 tests
,它是一个 Map<String, String>
。因此,您正在尝试从 YAML 序列构建 Java Map
。 SnakeYaml 理所当然地抱怨它不能那样做。
你的 YAML 结构看起来像你想做这样的事情:
public class YamlTestDataFile {
public static final class Test {
private String className;
public String param;
public String value;
public String getClass() { return className; }
public void setClass(final String value) { className = value; }
}
private List<Test> tests;
public List<Test> getTests() {
return tests;
}
public void setTests(List<Test> tests) {
this.tests = tests;
}
}
请注意 class
是 Java 中的关键字,因此我们需要 getter 和 setter 来加载该值。
类型擦除阻止 SnakeYaml 查看 tests
列表的通用参数是什么。因此,我们需要告诉它这是一个Test
的列表。让我们适当修改加载代码:
Constructor constructor = new Constructor(YamlTestDataFile.class);
TypeDescription dataDesc = new TypeDescription(YamlTestDataFile.class);
dataDesc.putListPropertyType("tests", YamlTestDataFile.Test.class);
constructor.addTypeDescription(dataDesc);
Yaml yaml = new Yaml(constructor);
InputStream in = ClassLoader.getSystemResourceAsStream("testData.yml");
testData = yaml.loadAs(in, YamlTestDataFile.class);
提示:代码未经测试。