C++實用技術 – YAML & JSON互轉

YAML

YAML是“YAML不是一種標記語言”的外語縮寫 (見前方參考資料原文內容);但爲了強調這種語言以數據做爲中心,而不是以置標語言爲重點,而用返璞詞重新命名。它是一種直觀的能夠被電腦識別的數據序列化格式,是一個可讀性高並且容易被人類閱讀,容易和腳本語言交互,用來表達資料序列的編程語言。
它是類似於標準通用標記語言的子集XML的數據描述語言,語法比XML簡單很多。(來自百度百科的介紹)

YAML-CPP

C++的常用YAML處理庫YAML-CPP

安裝部署

git clone https://github.com/jbeder/yaml-cpp.git
cd yaml-cpp
mkdir build
cd build
cmake -DBUILD_SHARED_LIBS=ON .. //-DBUILD_SHARED_LIBS=ON 啓用動態庫
make -j
make install

JSON

JSON(JavaScript Object Notation, JS 對象簡譜) 是一種輕量級的數據交換格式。它基於 ECMAScript (歐洲計算機協會制定的js規範)的一個子集,採用完全獨立於編程語言的文本格式來存儲和表示數據。簡潔和清晰的層次結構使得 JSON 成爲理想的數據交換語言。 易於人閱讀和編寫,同時也易於機器解析和生成,並有效地提升網絡傳輸效率。(來自百度百科的介紹)

JSONCPP

C++的常用json解析庫

安裝部署

git clone https://github.com/open-source-parsers/jsoncpp.git
cd jsoncpp
mkdir build
cd build
cmake ..
make -j
make install

代碼

頭文件

#include <yaml-cpp/yaml.h> //yaml-cpp頭文件
#include <json/json.h>     //jsoncpp頭文件
#include <iostream>

YamlToJson

將YAML::Node 轉化成 JSon::Value

bool YamlToJson(const YAML::Node& ynode, Json::Value& jnode) {
    try {
        if(ynode.IsScalar()) {
            Json::Value v(ynode.Scalar());
            jnode.swapPayload(v);
            return true;
        }
        if(ynode.IsSequence()) {
            for(size_t i = 0; i < ynode.size(); ++i) {
                Json::Value v;
                if(convert_yaml_to_json(ynode[i], v)) {
                    jnode.append(v);
                } else {
                    return false;
                }
            }
        } else if(ynode.IsMap()) {
            for(auto it = ynode.begin();
                    it != ynode.end(); ++it) {
                Json::Value v;
                if(convert_yaml_to_json(it->second, v)) {
                    jnode[it->first.Scalar()] = v;
                } else {
                    return false;
                }
            }
        }
    } catch(...) {
        return false;
    }
    return true;
}

JsonToYaml

將JSon::Value轉化成YAML::Node

bool JsonToYaml(const Json::Value& jnode, YAML::Node& ynode) {
    try {
        if(jnode.isArray()) {
            for(int i = 0; i < jnode.size(); ++i) {
                YAML::Node n;
                if(convert_json_to_yaml(jnode[i], n)) {
                    ynode.push_back(n);
                } else {
                    return false;
                }
            }
        } else if(jnode.isObject()) {
            for(auto it = jnode.begin();
                    it != jnode.end();
                    ++it) {
                YAML::Node n;
                if(convert_json_to_yaml(*it, n)) {
                    ynode[it.name()] = n;
                } else {
                    return false;
                }
            }
        } else {
            ynode = jnode.asString();
        }
    } catch (...) {
        return false;
    }
    return true;
}

測試代碼

test.yaml文件

logs:
    - name: root
      level: info
      appenders:
          - type: FileLogAppender
            file: "xxx.log"
          - type: StdoutLogAppender
    - name: system
      level: error
      appenders:
          - type: FileLogAppender
            file: "yyy.log"
          - type: StdoutLogAppender

測試代碼


//將Json轉成string
std::string JsonToString(const Json::Value& json) {
    Json::FastWriter w;
    return w.write(json);
}

int main(int argc, char** argv) {
    //加載yaml文件
    YAML::Node node = YAML::LoadFile("test.yml");
    Json::Value value;
    YamlToJson(node, value);
    std::cout << JsonToString(value) << std::endl;
    YAML::Node nnode;
    bool v = JsonToYaml(value, nnode);
    std::cout << " =========================== " << std::endl;
    std::cout << nnode << std::endl;
    std::cout << " ===========================" << std::endl;
    std::cout << node << std::endl;
    return 0;
}

輸出結果

{"logs":[{"appenders":[{"file":"xxx.log","type":"FileLogAppender"},{"type":"StdoutLogAppender"}],"level":"info","name":"root"},{"appenders":[{"file":"yyy.log","type":"FileLogAppender"},{"type":"StdoutLogAppender"}],"level":"error","name":"system"}]}

 ===========================
logs:
  - appenders:
      - file: xxx.log
        type: FileLogAppender
      - type: StdoutLogAppender
    level: info
    name: root
  - appenders:
      - file: yyy.log
        type: FileLogAppender
      - type: StdoutLogAppender
    level: error
    name: system
 ===========================
logs:
  - name: root
    level: info
    appenders:
      - type: FileLogAppender
        file: xxx.log
      - type: StdoutLogAppender
  - name: system
    level: error
    appenders:
      - type: FileLogAppender
        file: yyy.log
      - type: StdoutLogAppender

總結

YAML 和 Json 都是結構化標記語言。善用遞歸,將Yaml對應的結構轉化成Json的對應的結構。(反之亦然)

編程思想:善用遞歸和循環

其他

github: https://github.com/sylar-yin/sylar
視頻地址: https://www.bilibili.com/video/av53129011/
個人主頁:http://www.sylar.top/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章