C# yaml 配置文件的用法(一)

news2024/12/25 9:07:02

目录

一、简介

二、yaml 的符号

1.冒号

2.短横杆

3.文档分隔符

4.保留换行符

5.注释

6.锚点

7.NULL值

8.合并


一、简介

YAML(YAML Ain't Markup Language)是一种数据序列化标准,广泛用于配置文件、数据交换和存储。YAML的设计目标是易于阅读和编写,同时也易于机器解析和生成。以下是YAML的一些关键特点和用途的介绍:

  1. 简洁性:yaml 使用缩进和简洁的语法来表示数据结构,这使得它比 XML 或 Json 等格式更易于阅读和编写。

  2. 数据类型支持:yaml 支持多种数据类型,包括标量(如字符串、整数、浮点数)、序列(列表)、映射(字典)以及复杂的数据结构。

  3. 跨语言支持:yaml 可以被多种编程语言解析和生成,包括 Python、Ruby、Java、JavaScript 等,这使得它在不同系统间的数据交换中非常有用。

  4. 配置文件:yaml 常用于编写配置文件,因为它的人类可读性和灵活性使得配置管理变得简单。例如,Docker 和Kubernetes 都使用 yaml 来定义容器和集群的配置。

  5. 文档分离:yaml 支持文档分离,即一个文件中可以包含多个独立的 yaml 文档,每个文档由三个破折号(---)分隔。

  6. 引用和锚点:YAML允许使用引用和锚点来避免数据重复,这可以提高数据的可维护性和减少错误。

  7. 兼容性:YAML可以与JSON相互转换,这意味着YAML文件可以很容易地转换为JSON格式,反之亦然。

yaml 有以下基本规则:

1. 大小写敏感。

2. 使用缩进表示层级关系,缩进时不允许使用Tab键,只允许使用空格键,缩进的空格数不重要,只要元素左侧能对齐就可。

3.空格,在 value 的值前边必须有空格,否则读取时会报错,比如:name:  jack,而不是 name:jack,键值对的冒号后面至少有一个空格。

4.引号,value 的值如果是字符串,可以用引号也可以不用,单引号和双引号都可以。

5. yaml 兼容 Json 的语法,插件 YamlDotNet 同样也可以读写 Json。

yaml 在读取性能上不如 Json,但在需要手写配置文件的时候,yaml 要比 Json 方便不少,不用添加那么多对称的大括号(花括号)和中括号(方括号),读起来也更简单易懂,并且在多个编程语言中都是通用的。

文章的第二部分:

C# yaml 配置文件的用法(二)-CSDN博客

二、yaml 的符号

这里只介绍几个常用的符号,这不是 yaml 所有运算符,有需要的可以参考官方文档 The Official YAML Web Site

在使用 C# 进行读写时,需要安装一个插件 YamlDotNet

YamlDotNet 是开源的,github 可以找到对应的源码。

1.冒号

( : )冒号用于键值对的分隔,冒号后必须跟一个空格

username: admin  
password: 123456

C# 实例:

using System;
using System.Collections.Generic;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

namespace yaml_test
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string yaml = 
@"
name: zhangsan
";
            var deserializer = new DeserializerBuilder()
                .WithNamingConvention(CamelCaseNamingConvention.Instance)
                .Build();
            var data = deserializer.Deserialize<Dictionary<string, object>>(yaml);

            string name = data["name"] as string;
            Console.WriteLine("名字:{0}", name);

            Console.ReadKey();
        }
    }
}

运行:

2.短横杆

( - )短横杆用于表示列表(数组)的开始

fruits:  
  - Apple  
  - Banana  
  - Cherry

C# 实例:

using System;
using System.Collections.Generic;
using System.Linq;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

namespace yaml_test
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string yaml =
@"
fruits:  
  - Apple  
  - Banana  
  - Cherry
";
            var deserializer = new DeserializerBuilder()
                .WithNamingConvention(CamelCaseNamingConvention.Instance)
                .Build();
            var data = deserializer.Deserialize<Dictionary<string, object>>(yaml);

            if (data.ContainsKey("fruits") && data["fruits"] is IList<object> fruitsList)
            {
                string[] fruitsArray = fruitsList.Cast<string>().ToArray();
                Console.WriteLine(string.Join(", ", fruitsArray));
            }

            Console.ReadKey();
        }
    }
}

运行:

3.文档分隔符

使用三个连字符(---)表示一个YAML文档的开始,可选地使用三个点(...)表示文档的结束(但在实践中通常省略)。

---  
# 第一个文档  
username: admin  
---  
# 第二个文档  
name: Project A  
description: A new project  
...

4.保留换行符

| 和 > 用于处理多行字符串,其中 | 保留字符串的换行符,而 > 将换行符转换为空格。

poem: |  
  胜日寻芳泗水滨,
  无边光景一时新。
  等闲识得东风面,
  万紫千红总是春。

description: >  
  风和日丽之时游览在泗水之滨,
  无边无际的风光让人耳目一新。
  谁都可以看出春的面貌,万紫千红,
  到处都是百花开放的春景。

C# 实例:

using System;
using System.Collections.Generic;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

namespace yaml_test
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string yaml =
@"
poem: |  
  胜日寻芳泗水滨,
  无边光景一时新。
  等闲识得东风面,
  万紫千红总是春。

description: >  
  风和日丽之时游览在泗水之滨,
  无边无际的风光让人耳目一新。
  谁都可以看出春的面貌,万紫千红,
  到处都是百花开放的春景。
";
            var deserializer = new DeserializerBuilder()
                .WithNamingConvention(CamelCaseNamingConvention.Instance)
                .Build();
            var data = deserializer.Deserialize<Dictionary<string, object>>(yaml);

            string poem = data["poem"] as string;
            Console.WriteLine(poem);
            Console.WriteLine("===============");
            string description = data["description"] as string;
            Console.WriteLine(description);
            Console.ReadKey();
        }
    }
}

运行:

5.注释

使用井号(#)进行单行注释。

#这是一个注释  
username: admin  
password: 123456  #密码 

6.锚点

如果你有一个值需要在多个地方重复使用,可以使用 yaml 的锚点和别名功能来避免重复写入。锚点(&)用于标记一个节点,而别名(*)用于引用这个锚点。

比如下面的案例中,ip 这个值需要在很多的地方用到,我们就可以使用 &ip 来标记一个锚点,然后使用 *ip 来引用。

ipAddress: &ip '192.168.1.1'

server1:
  name: 'Server 1'
  ip: *ip

server2:
  name: 'Server 2'
  ip: *ip

server3:
  name: 'Server 3'
  ip: *ip

C# 实例:

using System;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

namespace yaml_test
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string yaml =
@"
ipAddress: &ip '192.168.1.1'
server1:
  name: 'Server 1'
  ip: *ip
server2:
  name: 'Server 2'
  ip: *ip
server3:
  name: 'Server 3'
  ip: *ip
";
            var deserializer = new DeserializerBuilder()
             .WithNamingConvention(CamelCaseNamingConvention.Instance)
             .Build();

            var config = deserializer.Deserialize<ServersConfig>(yaml);
            Console.WriteLine($"Server 1: Name = {config.Server1.Name}, IP = {config.Server1.Ip}");
            Console.WriteLine($"Server 2: Name = {config.Server2.Name}, IP = {config.Server2.Ip}");
            Console.WriteLine($"Server 3: Name = {config.Server3.Name}, IP = {config.Server3.Ip}");

            Console.ReadKey();
        }
    }
}

public class Server
{
    public string Name { get; set; }
    public string Ip { get; set; }
}

public class ServersConfig
{
    public string IpAddress { get; set; }
    public Server Server1 { get; set; }
    public Server Server2 { get; set; }
    public Server Server3 { get; set; }
}

运行:

由于 yaml 不支持字符串的拼接,只能在编程语言中自行合并,如果确实有这个需求的话,只能在 yaml 中使用编程语言更加方便的读取方式,比如数组,yaml 数组中也是支持使用瞄点的。

ipAddress: &ip 'http://192.168.1.1'
server1:
  name: 'Server 1'
  ip: [*ip,'/biz/getVersion']
server2:
  name: 'Server 2'
  ip: [*ip, '/biz/getName']
server3:
  name: 'Server 3'
  ip: [*ip, '/biz/getAge']

C# 实例:

using System;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

namespace yaml_test
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string yaml =
@"
ipAddress: &ip 'http://192.168.1.1'
server1:
  name: 'Server 1'
  ip: [*ip,'/biz/getVersion']
server2:
  name: 'Server 2'
  ip: [*ip, '/biz/getName']
server3:
  name: 'Server 3'
  ip: [*ip, '/biz/getAge']
";
            var deserializer = new DeserializerBuilder()
             .WithNamingConvention(CamelCaseNamingConvention.Instance)
             .Build();

            var config = deserializer.Deserialize<ServersConfig>(yaml);
            Console.WriteLine($"Server 1: Name = {config.Server1.Name}, IP = {string.Join("", config.Server1.Ip)}");
            Console.WriteLine($"Server 2: Name = {config.Server2.Name}, IP = {string.Join("", config.Server2.Ip)}");
            Console.WriteLine($"Server 3: Name = {config.Server3.Name}, IP = {string.Join("", config.Server3.Ip)}");

            Console.ReadKey();
        }
    }
}

public class Server
{
    public string Name { get; set; }
    public string[] Ip { get; set; }
}

public class ServersConfig
{
    public string IpAddress { get; set; }
    public Server Server1 { get; set; }
    public Server Server2 { get; set; }
    public Server Server3 { get; set; }
}

运行:

7.NULL值

可以用 ~null 来表示空值。例如:

value: ~
another_value: null

C# 实例:

using System;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

namespace yaml_test
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string yaml =
@"
value: ~
another_value: null            
";
            var deserializer = new DeserializerBuilder()
             .WithNamingConvention(CamelCaseNamingConvention.Instance)
             .Build();

            var data = deserializer.Deserialize<dynamic>(yaml);
            string value = data["value"];
            string another_value = data["another_value"];
            Console.WriteLine("value:{0}", value);
            Console.WriteLine("another_value:{0}", another_value);

            Console.ReadKey();
        }
    }
}

运行:

断点看看

8.合并

<<  是一个合并的语法,用于将一个映射(字典)的内容合并到另一个映射中。这种语法通常与锚和别名一起使用,以便重用和继承。

defaults: &defaults
  name: John
  age: 30

person1:
  <<: *defaults  # 合并 defaults 的内容
  location: USA

person2:
  <<: *defaults  # 合并 defaults 的内容
  location: Canada

合并后的结构将是:

person1:
  name: John
  age: 30
  location: USA

person2:
  name: John
  age: 30
  location: Canada

由于插件 YamlDotNet 目前并不支持合并语法(<<),所以这里就不做演示了,但它不代表所有编程语言都不支持合并语法,在有些编程语言中它是支持的,比如:Python 

文章的第二部:

C# yaml 配置文件的用法(二)-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1945457.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kotlin 协程 — 基础

Kotlin 协程 — 基础 协程已经存在一段时间了&#xff0c;关于它的各种文章也很多。但我发现想要了解它还比较费时&#xff0c;所以我花了一段时间才真正理解了协程的基础知识以及它的工作原理。因此&#xff0c;我想分享一些我理解到的内容。 什么是协程&#xff1f; 协程代表…

【MySQL进阶之路 | 高级篇】事务的ACID特性

1. 数据库事务概述 事务是数据库区别于文件系统的重要特性之一&#xff0c;当我们有了事务就会让数据库始终保持一致性&#xff0c;同时我们还能通过事务的机制恢复到某个时间点&#xff0c;这样可以保证给已提交到数据库的修改不会因为系统崩溃而丢失。 1.1 基本概念 事务&…

企业微信获客助手广告平台深度回传/双回传设置教程参考

很多商家在使用【转化宝】进行推广时只采用了单回传&#xff0c;其实很多情况下单回传即可满足推广模型优化需求&#xff1b;但是最近很多专业化广告运营的代投或运营都开始采用双回传&#xff0c;【转化宝】支持抖音巨量引擎、百度营销广告、快手广告、腾讯广告等均支出深度优…

微信小程序开发:项目程序代码构成

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

开源模型应用落地-LangChain高阶-记忆组件-ConversationBufferMemory正确使用(一)

一、前言 LangChain 的记忆组件发挥着至关重要的作用&#xff0c;其旨在协助大语言模型&#xff08;LLM&#xff09;有效地留存历史对话信息。通过这一功能&#xff0c;使得大语言模型在对话过程中能够更出色地维持上下文的连贯性和一致性&#xff0c;进而能够像人类的记忆运作…

【网络安全】构建稳固与安全的网络环境:从“微软蓝屏”事件中汲取的教训

发生什么事了&#xff1f; 近日&#xff0c;一次由微软视窗系统软件更新引发的全球性“微软蓝屏”事件&#xff0c;不仅成为科技领域的热点新闻&#xff0c;更是一次对全球IT基础设施韧性与安全性的深刻检验。这次事件&#xff0c;源于美国电脑安全技术公司“众击”提供的一个…

中断和EXIT原理介绍

中断和EXIT原理介绍 一、中断的介绍&#xff1f;二、EXIT的介绍1.EXIT作用2.EXIT的详情3.EXIT中AFIO复用的作用4.STM32中AFIO复用作用 一、中断的介绍&#xff1f; 二、EXIT的介绍 EXTI&#xff08;Extern Interrupt&#xff09;外部中断 1.EXIT作用 EXTI可以监测指定GPIO口…

Java学习笔记(五)数组、冒泡排序

Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍Java数组、冒泡排序使用以及部分理论知识 &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主收将持续更新学习记录获&#xff0c;友友们有任何问题可以在评论区留言 …

力扣SQL50 指定日期的产品价格 双重子查询 coalesce

Problem: 1164. 指定日期的产品价格 coalesce 的使用 简洁版 &#x1f468;‍&#x1f3eb; 参考题解 select distinct p1.product_id,coalesce((select p2.new_pricefrom Products p2where p2.product_id p1.product_id and p2.change_date < 2019-08-16order by p2.…

Web前端Promise

Promise介绍与使用 Promise是什么&#xff1f; 1.抽象表达&#xff1a; Promise是一门新的技术&#xff08;ES6规范&#xff09;Promise是JS中进行异步编程的新解决方案备注&#xff1a;旧方案是单纯使用回调函数 2.具体表达&#xff1a; 从语法上来说&#xff1a;Promise…

xmind--如何快速将Excel表中多列数据,复制到XMind分成多级主题

每次要将表格中的数据分成多级时&#xff0c;只能复制粘贴吗 快来试试这个简易的方法吧 这个是原始的表格&#xff0c;分成了4级 步骤&#xff1a; 1、我们可以先按照这个层级设置下空列&#xff08;后买你会用到这个空列&#xff09; 二级不用加、三级前面加一列、四级前面加…

前端:Vue学习 - 购物车项目

前端&#xff1a;Vue学习 - 购物车项目 1. json-server&#xff0c;生成后端接口2. 购物车项目 - 实现效果3. 参考代码 - Vuex 1. json-server&#xff0c;生成后端接口 全局安装json-server&#xff0c;json-server官网为&#xff1a;json-server npm install json-server -…

C++ 设计模式(五)——状态模式

状态模式 序言理解源码 序言 设计模式只是一个抽象的设计模式方法&#xff0c;并不是一个固定使用的搭配&#xff0c;就算是普通switch语句&#xff0c;Map&#xff0c;乃至状态机都是状态模式的其中一种实现方法 状态模式看起来好像和策略模式差不多&#xff0c;主要是其的侧…

JavaScript构造函数小挑战

// 编码挑战 #1 /* 使用构造函数实现一辆汽车。一辆汽车有一个品牌和一个速度属性。speed 属性是汽车当前的速度&#xff0c;单位为 km/h&#xff1b; a. 执行一个 “accelerate ”方法&#xff0c;将汽车的速度提高 10&#xff0c;并将新速度记录到控制台&#xff1b; 3. a.…

若依Vue前后端分离版如何部署(windows)(超详细)

一、项目环境准备 下面是项目所需要准备的环境 Node.js redis 1、Node.js下载 下面进入官网可以下载Node.js — 在任何地方运行 JavaScript (nodejs.org)https://nodejs.org/zh-cn 下载完成安装后&#xff0c;需要配置环境变量&#xff0c;首先复制以下nodejs的安…

商汤提出的BRECQ量化框架是个什么?

商汤提出的BRECQ量化框架是个什么&#xff1f; 引言 近年来&#xff0c;深度学习在多个领域取得了显著进展&#xff0c;但其巨大的计算成本和内存占用问题逐渐凸显。为了压缩和加速已训练好的网络&#xff0c;量化成为了一种重要的技术手段。量化主要分为两类&#xff1a;量化…

DAMA学习笔记(七)-数据集成和互操作

1.引言 数据集成和互操作(DII)描述了数据在不同数据存储、应用程序和组织这三者内部和之间进行移动和整合的相关过程。数据集成是将数据整合成物理的或虚拟的一致格式。数据互操作是多个系统之间进行通信的能力。数据集成和互操作的解决方案提供了大多数组织所依赖的基本数据管…

数据库解析一维和二维简易JSON,

项目还在使用Oracle11&#xff0c;不支持后续官方的json解析方式&#xff0c; 在 前年、去年、今年 接连 遇到json解析问题后&#xff08;其实是公司的轮子效率太慢&#xff0c;太复杂&#xff0c;决定自己造个轮子&#xff0c;看看到底为什么慢&#xff0c;是不是真的很复杂&a…

计算机网络八股文(四)

目录 61.客户端调用close()后的断开流程是怎样的&#xff1f; 62.没有accept可以建立TCP连接吗&#xff1f; 63.没有listen可以建立TCP连接吗&#xff1f; 64.什么是TCP半连接队列&#xff08;SYN队列&#xff09;和全连接队列&#xff08;accept队列&#xff09;&#xff…

质量问题到底是谁的责任?

在竞争日益激烈的市场环境中&#xff0c;产品质量是企业生存与发展的基石。每当谈及生产企业的质量问题&#xff0c;我们往往不由自主地思考&#xff1a;在这一复杂而精细的生产链条中&#xff0c;究竟是谁该为质量问题负责&#xff1f; 必须明确一个无可争议的事实&#xff1…