使用字符串路径获取 YAMLDotNet/SharpYAML 节点(例如 "category.object.parameter")
Getting a YAMLDotNet/SharpYAML node using a string path (such as "category.object.parameter")
在我使用过的所有其他 YAML 库中,只需在 get 函数中将路径作为字符串输入即可获取节点,YAMLDotNet 中是否有类似的功能?
看起来不像,但有一个开放的功能请求。如果您有兴趣,可以关注:https://github.com/aaubry/YamlDotNet/issues/333
我决定阅读 yaml 文件,然后将其转换为 json,如果有人感兴趣,这里是代码:
public JObject root = null;
public void ReadLanguage()
{
try
{
// Reads file contents into FileStream
FileStream stream = File.OpenRead(languagesPath + filename + ".yml");
// Converts the FileStream into a YAML Dictionary object
var deserializer = new DeserializerBuilder().Build();
var yamlObject = deserializer.Deserialize(new StreamReader(stream));
// Converts the YAML Dictionary into JSON String
var serializer = new SerializerBuilder()
.JsonCompatible()
.Build();
string jsonString = serializer.Serialize(yamlObject);
root = JObject.Parse(jsonString);
plugin.Info("Successfully loaded language file.");
}
catch (Exception e)
{
if (e is DirectoryNotFoundException)
{
plugin.Error("Language directory not found.");
}
else if (e is UnauthorizedAccessException)
{
plugin.Error("Language file access denied.");
}
else if (e is FileNotFoundException)
{
plugin.Error("'" + filename + ".yml' was not found.");
}
else if (e is JsonReaderException || e is YamlException)
{
plugin.Error("'" + filename + ".yml' formatting error.");
}
plugin.Error("Error reading language file '" + filename + ".yml'. Deactivating plugin...");
plugin.Debug(e.ToString());
plugin.Disable();
}
}
如果可以避免,我不建议这样做,我碰巧需要使用 yaml,如果代码中没有字符串路径,我会发疯的。
我试了一下。这段代码可能需要一些清理和更多的错误检查,但它似乎可以工作。一般的想法是你传入一个路径,例如 /someNode/anotherNode
并且它将 return 该位置的 YamlNode:
using System;
using System.Collections.Generic;
using YamlDotNet.RepresentationModel;
namespace YamlTransform
{
public static class Extensions
{
public static YamlNode XPath(this YamlDocument doc, string path)
{
if (!(doc.RootNode is YamlMappingNode mappingNode)) // Cannot search non mapping nodes
{
return null;
}
var sections = new Queue<string>(path.Split('/', StringSplitOptions.RemoveEmptyEntries));
while (sections.Count > 1)
{
string nextSection = sections.Dequeue();
var key = new YamlScalarNode(nextSection);
if (mappingNode == null || !mappingNode.Children.ContainsKey(key))
{
return null; // Path does not exist
}
mappingNode = mappingNode[key] as YamlMappingNode;
}
return mappingNode?[new YamlScalarNode(sections.Dequeue())];
}
}
}
在我使用过的所有其他 YAML 库中,只需在 get 函数中将路径作为字符串输入即可获取节点,YAMLDotNet 中是否有类似的功能?
看起来不像,但有一个开放的功能请求。如果您有兴趣,可以关注:https://github.com/aaubry/YamlDotNet/issues/333
我决定阅读 yaml 文件,然后将其转换为 json,如果有人感兴趣,这里是代码:
public JObject root = null;
public void ReadLanguage()
{
try
{
// Reads file contents into FileStream
FileStream stream = File.OpenRead(languagesPath + filename + ".yml");
// Converts the FileStream into a YAML Dictionary object
var deserializer = new DeserializerBuilder().Build();
var yamlObject = deserializer.Deserialize(new StreamReader(stream));
// Converts the YAML Dictionary into JSON String
var serializer = new SerializerBuilder()
.JsonCompatible()
.Build();
string jsonString = serializer.Serialize(yamlObject);
root = JObject.Parse(jsonString);
plugin.Info("Successfully loaded language file.");
}
catch (Exception e)
{
if (e is DirectoryNotFoundException)
{
plugin.Error("Language directory not found.");
}
else if (e is UnauthorizedAccessException)
{
plugin.Error("Language file access denied.");
}
else if (e is FileNotFoundException)
{
plugin.Error("'" + filename + ".yml' was not found.");
}
else if (e is JsonReaderException || e is YamlException)
{
plugin.Error("'" + filename + ".yml' formatting error.");
}
plugin.Error("Error reading language file '" + filename + ".yml'. Deactivating plugin...");
plugin.Debug(e.ToString());
plugin.Disable();
}
}
如果可以避免,我不建议这样做,我碰巧需要使用 yaml,如果代码中没有字符串路径,我会发疯的。
我试了一下。这段代码可能需要一些清理和更多的错误检查,但它似乎可以工作。一般的想法是你传入一个路径,例如 /someNode/anotherNode
并且它将 return 该位置的 YamlNode:
using System;
using System.Collections.Generic;
using YamlDotNet.RepresentationModel;
namespace YamlTransform
{
public static class Extensions
{
public static YamlNode XPath(this YamlDocument doc, string path)
{
if (!(doc.RootNode is YamlMappingNode mappingNode)) // Cannot search non mapping nodes
{
return null;
}
var sections = new Queue<string>(path.Split('/', StringSplitOptions.RemoveEmptyEntries));
while (sections.Count > 1)
{
string nextSection = sections.Dequeue();
var key = new YamlScalarNode(nextSection);
if (mappingNode == null || !mappingNode.Children.ContainsKey(key))
{
return null; // Path does not exist
}
mappingNode = mappingNode[key] as YamlMappingNode;
}
return mappingNode?[new YamlScalarNode(sections.Dequeue())];
}
}
}