Java 使用snakeyaml 将.yml 文件加载到hashmaps(导入junit 库)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21141120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 06:52:24  来源:igfitidea点击:

Load .yml file into hashmaps using snakeyaml (import junit library)

javaopencvjunitloadsnakeyaml

提问by snake plissken

I am trying to load opencv's .yml file into arrayLists mean, projection and labels. I ve create those three arraylists and I am trying to parse into them the elements from the .yml file. I ve found snakeYAML documentation . However I didnt find a way to do so properly. I am trying to use

我正在尝试将 opencv 的 .yml 文件加载到 arrayLists 均值、投影和标签中。我已经创建了这三个数组列表,并且正在尝试将 .yml 文件中的元素解析为它们。我找到了snakeYAML 文档。但是我没有找到正确的方法。我正在尝试使用

  final String fileName = "train.yml";
  opencvmatrix mat = new opencvmatrix(); 
  Yaml yaml = new Yaml();

  try {
     InputStream ios = new FileInputStream(new File(fileName));

     // Parse the YAML file and return the output as a series of Maps and Lists
     Map<String,Object> result = (Map<String,Object>)yaml.load(ios);
     System.out.println(result.toString());
     Collection<Object> file = result.values();



  } catch (Exception e) {
     e.printStackTrace();
  }

}

}

I am receiving as an error the following:

我收到以下错误消息:

Exception in thread "main" while scanning a directive
in 'reader', line 1, column 1:
%YAML:1.0
^
expected alphabetic or numeric character, but found :(58)
in 'reader', line 1, column 6:
%YAML:1.0
     ^

at org.yaml.snakeyaml.scanner.ScannerImpl.scanDirectiveName(ScannerImpl.java:1269)
at org.yaml.snakeyaml.scanner.ScannerImpl.scanDirective(ScannerImpl.java:1221)
at org.yaml.snakeyaml.scanner.ScannerImpl.fetchDirective(ScannerImpl.java:614)
at org.yaml.snakeyaml.scanner.ScannerImpl.fetchMoreTokens(ScannerImpl.java:306)
at org.yaml.snakeyaml.scanner.ScannerImpl.checkToken(ScannerImpl.java:226)
at org.yaml.snakeyaml.parser.ParserImpl$ParseImplicitDocumentStart.produce(ParserImpl.java:195)
at org.yaml.snakeyaml.parser.ParserImpl.peekEvent(ParserImpl.java:158)
at org.yaml.snakeyaml.parser.ParserImpl.checkEvent(ParserImpl.java:143)
at org.yaml.snakeyaml.composer.Composer.getSingleNode(Composer.java:104)
at org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.java:120)
at org.yaml.snakeyaml.Yaml.loadFromReader(Yaml.java:481)
at org.yaml.snakeyaml.Yaml.load(Yaml.java:412)
at projectCV.main(projectCV.java:33)
Java Result: 1

EDIT1: I ve noticed that my problems stands for assertEquals which is a function of the class assert part of junit library. I cant find a way to import properly the library to my classpath. I am trying two things, download .jar file and ADD/Jar folder and from project properties->libraries->compile tests-> add library -> Junit 4.10. But I am still having issues.

EDIT1:我注意到我的问题代表 assertEquals,它是 junit 库的类断言部分的函数。我找不到将库正确导入到我的类路径的方法。我正在尝试两件事,下载 .jar 文件和 ADD/Jar 文件夹,并从项目属性->库->编译测试->添加库-> Junit 4.10。但我仍然有问题。

EDIT2: I change the YAML 1.0 to YAML 1.1, but nothing changes. I am still trying to find a suitable way to read the yml file.

EDIT2:我将 YAML 1.0 更改为 YAML 1.1,但没有任何变化。我仍在努力寻找一种合适的方式来读取 yml 文件。

       final String fileName = "train.yml";
  opencvmatrix mat = new opencvmatrix(); 
  Yaml yaml = new Yaml();

  try {
     InputStream ios = new FileInputStream(new File(fileName));

     // Parse the YAML file and return the output as a series of Maps and Lists
     Map<String,Object> result = (Map<String,Object>)yaml.load(ios);
     System.out.println(result.toString());
     Collection<Object> file = result.values();



  } catch (Exception e) {
     e.printStackTrace();
  }

}

}

WHen I am trying to run this code I am receiving:

当我尝试运行此代码时,我收到了:

Exception in thread "main" Can't construct a java object for tag:yaml.org,2002:opencv- 
matrix; exception=Class not found: opencv-matrix
in 'reader', line 3, column 7:
mean: !!opencv-matrix
      ^

EDIT3: I ve created a class opencvmatrix (like the name of .yml properties), with the properties rows, cols, dt, ArrayList data. The .yml file is like:

EDIT3:我创建了一个类 opencvmatrix(如 .yml 属性的名称),具有属性行、列、dt、ArrayList 数据。.yml 文件是这样的:

num_components: 19
num_components: 19
mean: !!opencvmatrix
rows: 1
cols: 3600
dt: d
data: [ 9.6842105263157890e+01, 1.0257894736842104e+02,
   1.0557894736842104e+02, 1.0794736842105263e+02,
   1.1752631578947367e+02, 1.1631578947368421e+02,
   1.1084210526315789e+02, 1.0373684210526315e+02,
   1.0052631578947368e+02, 9.5263157894736835e+01,
   9.0421052631578945e+01, 8.5631578947368411e+01,
   7.8684210526315780e+01, 7.2105263157894740e+01,
   6.9315789473684205e+01, 6.9105263157894740e+01,
   7.1052631578947370e+01, 7.9631578947368411e+01,
   9.0894736842105260e+01, 1.0121052631578947e+02,
   ....]
   projections:
   - !!opencvmatrix
   rows: 1
   cols: 19
   dt: d
   data: [ 1.6852352677811423e+03, -1.0112905042030820e+03,
      -1.3152188243875064e+03, 4.8298990155435700e+02,
      9.1980535900698968e+01, 6.5624763621018792e+02,
      -1.2380244625181117e+03, -1.8800931631152707e+02,
      -4.1473232893431384e+02, 5.7197035514178856e+02,
      4.9990276749703435e+02, 4.9062987890888604e+02,
      6.1928710580829818e+02, -1.2842392693864540e+03,
      2.4907719466932619e+01, 8.0299588479341844e+02,
      1.1621501008120421e+02, 1.0410492864645674e+02,
      8.5302163830384785e+01 ]
   - !!opencvmatrix
   rows: 1
   cols: 19
   dt: d
   data: [ -1.0313663745467784e+03, 1.9900404646205566e+03,
      -1.2844533156050284e+02, -4.3700867528097513e+02,
      6.6145551346834259e+02, -2.0562483671734990e+03,
      -1.9643774942432364e+02, 4.9329679854416281e+02,
      -2.0003326324501427e+02, 1.0737995038485865e+03,
      5.4161214984553695e+01, 4.7932826490658994e+02,
      8.6307152262273064e+02, 6.7413046532276610e+02,
      6.3835284527337114e+02, 4.1663169960066972e+02,
      3.5883912817427905e+01, -1.2935687563770381e+02,
      -1.6471877227400194e+03 ]
     ...
    labels: !!opencvmatrix
    rows: 1
    cols: 19
    dt: i
    data: [ 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3 ]

Now without changing the main code I am receiving the following error:

现在不更改主代码,我收到以下错误:

   Can't construct a java object for tag:yaml.org,2002:opencvmatrix; exception=No single
   argument constructor found for class opencvmatrix
   in 'reader', line 1, column 7:
   mean: !!opencvmatrix
      ^

采纳答案by snake plissken

I am finally trying the above code:

我终于在尝试上面的代码:

public static void main(String[] args) {
    // The path of your YAML file.
    final String fileName = "test.yml";
    ArrayList<String> key = new ArrayList<String>();
    ArrayList<String> value = new ArrayList<String>();
    Yaml yaml = new Yaml();

    try {
        InputStream ios = new FileInputStream(new File(fileName));

        // Parse the YAML file and return the output as a series of Maps and Lists
        Map< String, Object> result = (Map< String, Object>) yaml.load(ios);
        for (Object name : result.keySet()) {   

            key.add(name.toString());
            value.add(result.get(name).toString());    
        }

    } catch (Exception e) {
        e.printStackTrace();
    } 

     System.out.println(key + " " + value); }

Which actually reads .yml file and returns the keys and the correspondant values of the file. My problem is that value contains other objects which with their turn contains others Maps due to the order of the yaml file. Println shows the above in terminal:

它实际上读取 .yml 文件并返回文件的键和对应的值。我的问题是 value 包含其他对象,由于 yaml 文件的顺序,这些对象又包含其他 Maps。Println 在终端中显示以上内容:

[mean, eigenvalues, eigenvectors, projections, labels] [opencvmatrix@16e70aa, opencvmatrix@1a6e106, opencvmatrix@ff8927, [opencvmatrix@859445, opencvmatrix@1c94782, opencvmatrix@175e958, opencvmatrix@2acdad, opencvmatrix@254927, opencvmatrix@1e5c67f, opencvmatrix@4ace42, opencvmatrix@12b710e, opencvmatrix@10b6d81, opencvmatrix@142691b, opencvmatrix@102985e, opencvmatrix@16168c4, opencvmatrix@25417f, opencvmatrix@1ef0642, opencvmatrix@183d912, opencvmatrix@1204e58, opencvmatrix@1f78fae, opencvmatrix@1f9fe08, opencvmatrix@194ddfb], opencvmatrix@7996db]

How can I have access to the returned nested objects???

我怎样才能访问返回的嵌套对象???

Edit2: Actually I had to cast the returned objects from the .yaml file to a new class that I have to define. So my code for reading .yml elements (face recognizer trained elements):

Edit2:实际上我必须将返回的对象从 .yaml 文件转换为我必须定义的新类。所以我读取 .yml 元素的代码(人脸识别器训练的元素):

ArrayList<String> key = new ArrayList<String>();
    ArrayList<String> value = new ArrayList<String>();

    ArrayList<Object> obj = new ArrayList<Object>();
    ArrayList<Object> objected = new ArrayList<Object>();
    opencvmatrix mean = new opencvmatrix();
    opencvmatrix eigenValues = new opencvmatrix();
    opencvmatrix eigenVectors = new opencvmatrix();
    ArrayList<Object> opencvmatrix4 = new ArrayList<Object>();
    opencvmatrix labels = new opencvmatrix();
     opencvmatrix opencvmatrix6 = new opencvmatrix();
    ArrayList<ArrayList<Double>> projections = new ArrayList<ArrayList<Double>>();
    Yaml yaml = new Yaml();

    try {
        InputStream ios = new FileInputStream(new File(fileName));
        // Parse the YAML file and return the output as a series of Maps and Lists
        Map< String, Object> result = (Map< String, Object>) yaml.load(ios);
        for (Object name : result.keySet()) {
            key.add(name.toString());
            obj.add(result.get(name));
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    File file = new File("eigenvalues.txt");
    // creates the file
    file.createNewFile();
    // creates a FileWriter Object
    FileWriter writer = new FileWriter(file);
        // Writes the content to the file


    mean = (opencvmatrix) (obj.get(0));
    eigenValues = (opencvmatrix) (obj.get(1));
    eigenVectors = (opencvmatrix) (obj.get(2));

    opencvmatrix4 = (ArrayList<Object>) obj.get(3);

    for(int i=0; i<opencvmatrix4.size(); i++){

        opencvmatrix6 = (opencvmatrix)opencvmatrix4.get(i);
        projections.add(opencvmatrix6.data);
    }

    //System.out.println(projections.get(0).size());

    labels = (opencvmatrix) (obj.get(4));
    //System.out.println(obj3.data.size());

    writer.write(eigenVectors.data.get(0) + "      ");
    temp.add(eigenVectors.data.get(0));
    eigenMatrix.add(temp);

    for (int i = 1; i < eigenVectors.data.size(); i++) {

        if (i % 3600 == 0) {
            writer.write("\n");
            eigenMatrix.add(temp);
            temp.clear();

        }

         writer.write(eigenVectors.data.get(i) + "      ");
        temp.add(eigenVectors.data.get(i));

    }
    writer.flush();
    writer.close();

回答by maslovalex

SnakeYaml is YAML 1.1 parser and you are trying to parse YAML 1.0. It's indicated by "%YAML:1.0" directive (see 3.2.3.3 in the specs http://yaml.org/spec/1.0/#id2558635)

SnakeYaml 是 YAML 1.1 解析器,您正在尝试解析 YAML 1.0。它由“%YAML:1.0”指令指示(参见规范http://yaml.org/spec/1.0/#id2558635 中的3.2.3.3 )

YAML 1.1 has different syntax - "%YAML 1.1" (see 7.1.1 in the specs http://yaml.org/spec/1.1/#id895631)

YAML 1.1 具有不同的语法 - “%YAML 1.1”(参见规范http://yaml.org/spec/1.1/#id895631 中的7.1.1 )

You can try to remove that directive from your file or change it to "%YAML 1.1" and hope it will be parsed correctly.

您可以尝试从您的文件中删除该指令或将其更改为“%YAML 1.1”并希望它能够被正确解析。