How to Read a Yaml File

How can I parse a YAML file in Python

The easiest and purest method without relying on C headers is PyYaml (documentation), which can be installed via pip install pyyaml:

#!/usr/bin/env python

import yaml

with open("example.yaml", "r") as stream:
try:
print(yaml.safe_load(stream))
except yaml.YAMLError as exc:
print(exc)

And that's it. A plain yaml.load() function also exists, but yaml.safe_load() should always be preferred to avoid introducing the possibility for arbitrary code execution. So unless you explicitly need the arbitrary object serialization/deserialization use safe_load.

Note the PyYaml project supports versions up through the YAML 1.1 specification. If YAML 1.2 specification support is needed, see ruamel.yaml as noted in this answer.

Also, you could also use a drop in replacement for pyyaml, that keeps your yaml file ordered the same way you had it, called oyaml. View synk of oyaml here

How to read a YAML file

your yaml file must be

hits: 5
time: 5000000

your code should look like this:

package main

import (
"fmt"
"gopkg.in/yaml.v2"
"io/ioutil"
"log"
)

type conf struct {
Hits int64 `yaml:"hits"`
Time int64 `yaml:"time"`
}

func (c *conf) getConf() *conf {

yamlFile, err := ioutil.ReadFile("conf.yaml")
if err != nil {
log.Printf("yamlFile.Get err #%v ", err)
}
err = yaml.Unmarshal(yamlFile, c)
if err != nil {
log.Fatalf("Unmarshal: %v", err)
}

return c
}

func main() {
var c conf
c.getConf()

fmt.Println(c)
}

the main error was capital letter for your struct.

How to read a specific data from a yaml file inside a shell script

Here's an example with yq. All of the following assumes that the values do not contain newlines.

Given

$ cat test.yaml
---
test:
config:
abc: name1
xyz: name2

then

yq e '.test.config | to_entries | map(.value) | .[]' test.yaml

outputs

name1
name2

You can read them into variables like

{ read -r var1; read -r var2; } < <(yq e '.test.config | to_entries | map(.value) | .[]' test.yaml)
declare -p var1 var2
declare -- var1="name1"
declare -- var2="name2"

I would read them into an associative array with the yaml key though:

declare -A conf
while IFS="=" read -r key value; do conf["$key"]=$value; done < <(
yq e '.test.config | to_entries | map([.key, .value] | join("=")) | .[]' test.yaml
)
declare -p conf
declare -A conf=([abc]="name1" [xyz]="name2" )

Then you can write

echo "test config for abc is ${conf[abc]}"
# or
for var in "${!conf[@]}"; do printf "key %s, value %s\n" "$var" "${conf[$var]}"; done

I'm using "the Go implementation"

$ yq --version
yq (https://github.com/mikefarah/yq/) version 4.16.1

How to read from YAML file in java?

YAML has a list of recommended libraries for Java:
SnakeYAML, YamlBeans and eo-yaml

The most widely used of these is probably SnakeYAML. Baeldung has a very easy to understand tutorial here: https://www.baeldung.com/java-snake-yaml

[Edit to address new code and output in edit by OP]:

You also have some problems with the formatting and naming conventions you used. In your yaml file [brackets] are needed around any Lists, instance variables need to be camelCase, and any Strings need to be surrounded by quotes (including Object keys):

products:
"ProductA":
suite:
"SuiteName_A":
environment_1: ["A","B","C"]
environment_2: ["X","Y","Z"]
"SuiteName_B":
environment_1: ["E","F","G"]
environment_2: ["K","L","M"]
"ProductB":
suite:
"SuiteName_K":
environment_1: ["A1","B2","C3"]
environment_2: ["X1","Y1","Z1"]

You should try to match this in your bean naming convention. Also your 2nd setter needs to set Environment_2 instead of Environment_1. Here's how your entity classes would look.

Environment

package Configuration;

import java.util.ArrayList;

public class Environment {
private ArrayList<String> environment_1;
private ArrayList<String> environment_2;

public ArrayList<String> getEnvironment_1() {
return environment_1;
}

public void setEnvironment_1(ArrayList<String> environment_1) {
this.environment_1 = environment_1;
}

public ArrayList<String> getEnvironment_2() {
return environment_2;
}

public void setEnvironment_2(ArrayList<String> environment_2) {
this.environment_2 = environment_2;
}
}

SuiteNames

package Configuration;

import java.util.HashMap;

public class SuiteName {
private HashMap<String,Environment> suite;

public HashMap<String, Environment> getSuite() {
return suite;
}

public void setSuite(HashMap<String, Environment> suite) {
suite = suite;
}
}
package Configuration;

import java.util.HashMap;

public class Product {
private HashMap<String, SuiteName> products;

public HashMap<String, SuiteName> getProducts() {
return products;
}

public void setProducts(HashMap<String, SuiteName> products) {
this.products = products;
}
}

Edit:
In your main method you will probably want to use yaml.load(inputStream) to get the whole file in a HashMap. Based on your question in the comment I've added accessing the data structure.

DbClass

package Configuration;

import org.yaml.snakeyaml.Yaml;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;

public class DbClass {

public static void main(String[] args) throws FileNotFoundException {
Yaml yaml = new Yaml();
InputStream inputStream = new FileInputStream("path.yml");
System.out.println(inputStream);

HashMap yamlMap = yaml.load(inputStream);
for (Object o : yamlMap.entrySet()) {
System.out.println(o);
}
// Access HashMaps and ArrayList by key(s)
HashMap products = (HashMap) yamlMap.get("products");
HashMap product = (HashMap) products.get("ProductA");
HashMap suite = (HashMap) product.get("suite");
HashMap suiteName = (HashMap) suite.get("SuiteName_B");
ArrayList environment = (ArrayList) suiteName.get("environment_1");
System.out.println(environment);
}
}

Parsing yaml file with --- in python

Your input is composed of multiple YAML documents. For that you will need yaml.load_all() or better yet yaml.safe_load_all(). (The latter will not construct arbitrary Python objects outside of data-like structures such as list/dict.)

import yaml

with open('temp.yaml') as f:
temp = yaml.safe_load_all(f)

As hinted at by the error message, yaml.load() is strict about accepting only a single YAML document.

Note that safe_load_all() returns a generator of Python objects which you'll need to iterate over.

>>> gen = yaml.safe_load_all(f)
>>> next(gen)
{'name': 'first', 'cmp': [{'Some': 'first', 'top': {'top_rate': 16000, 'audio_device': 'pulse'}}]}
>>> next(gen)
{'name': 'second', 'components': [{'name': 'second', 'parameters': {'always_on': True, 'timeout': 200000}}]}

Reading from a YAML file in Kotlin

You need to include the jackson-dataformat-yaml dependency and then create your ObjectMapper like this:

val mapper = ObjectMapper(YAMLFactory()).registerModule(KotlinModule())

Read strongly typed yaml file in Typescript?

From what I can see when using @types/js-yaml is that load is not generic, meaning it does not accept a type parameter.

So the only way to get a type here is to use an assertion, for example:

const yaml = load(await readFile(filepath, "utf8")) as YourType;
const phrases = yaml.trainingPhrases;

Or in short:

const phrases = (load(await readFile(filepath, "utf8")) as YourType).trainingPhrases;

If you absolutely want a generic function, you can easily wrap the original, like:

import {load as original} from 'js-yaml';

export const load = <T = ReturnType<typeof original>>(...args: Parameters<typeof original>): T => load(...args);

And then you can use it as:

const phrases = load<YourType>('....').trainingPhrases;

Read YAML file like properties

you don't need to add separate yml. you add custom properties to application.yml or application-{env}.yml
Spring recognise it and you can it via

  1. @Value
  2. Spring environment
  3. Using Spring ConfigurationProperties


Related Topics



Leave a reply



Submit