C#通过IronRuby分析YAML
C#就没有比较好的Yaml的Parser,在nuGet上找了半天,找到一个parse,但是貌似有问题,yaml文件缩进一定要两个空格,不能是Tab,我狂晕。
后来自己想了一个办法来解决这个问题。就是C#调用用IronRuby来解析,然后再返回给C#。因为IronRuby完美的实现了Ruby 1.9的大部分,用它来分析Yaml应该是比较合适的。
新建一个工程YLab.Yaml 加入对Ironruby的dll的引用 下载了ironruby就知道了引用哪些了
建立一个文件夹YLab.Yaml
下面建立一个config.rb文件
# 作者 虞
# 时间 2011-6-6
# Path 变量定义了IronRuby的SearchPath
# rb文件中的require就是在SearchPath中查找的
# 这里的路径都是相对于应用程序根目录的相对路径
Path =
[
"RubyLib/ironruby",
"RubyLib/ruby/1.9.1",
"RubyLib/ruby/site_ruby/1.9.1"
]
def SearchPath
Path
end
再建立一个YLabYAML.rb文件
# 作者 虞
# 时间 2011-6-6
require "yaml"
class YYAML
def load(file)
YAML::load_file(file)
end
def parse(file)
YAML::parse_file(file)
end
end
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 using System.IO;
7
8 using Microsoft.Scripting.Hosting;
9 using IronRuby;
10
11 namespace YLab.YAML
12 {
13 public class YAML
14 {
15 private ScriptRuntime irb;
16 private ICollection<string> searchPath = new List<string>();
17 private dynamic yyaml;
18
19 public YAML()
20 {
21 irb = Ruby.CreateRuntime();
22 searchPath.Add(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory));
23 searchPath.Add(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"YLab.YAML"));
24 irb.GetRubyEngine().SetSearchPaths(searchPath);
25
26 dynamic rbCfg = irb.UseFile("config.rb");
27 var cfgSearchPath = rbCfg.SearchPath();
28 foreach (var path in cfgSearchPath)
29 {
30 searchPath.Add(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, (string)path));
31 }
32 irb.GetRubyEngine().SetSearchPaths(searchPath);
33 //ylabYAML = irb.UseFile("YLabYAML.rb");
34
35 var assembly = System.Reflection.Assembly.GetExecutingAssembly();
36
37 string code;
38
39 using (var stream = assembly.GetManifestResourceStream("YLab.YAML.YLab.YAML.YLabYAML.rb"))
40 {
41 using (TextReader rbReader = new StreamReader(stream)) {
42 code = rbReader.ReadToEnd();
43 }
44 }
45 irb.GetRubyEngine().Execute(code);
46 // irb.GetRubyEngine().Execute(@"\
47 // # 作者 虞
48 // # 时间 2011-6-6
49 // require 'yaml'
50 // class YYAML
51 // def load(file)
52 // YAML::load_file(file)
53 // end
54 //
55 // def parse(file)
56 // YAML::parse_file(file)
57 // end
58 // end
59 // ");
60
61 dynamic ruby = irb.Globals;
62 yyaml = ruby.YYAML.@new();
63
64 }
65
66 public dynamic LoadFile(string yamlFile)
67 {
68 return yyaml.load(yamlFile);
69
70 }
71
72 public dynamic ParseFile(string yamlFile)
73 {
74 return yyaml.parse(yamlFile);
75 }
76 }
77 }
这样就可以了
再建立一个consoleapp
先放一个要分析的yaml config.yaml
address: 10.0.0.86
port: 36
persons:
- name: 丁一
age: 30
- name: 王二
age: 33
然后是program.cs
{
YAML y = new YAML();
var config = y.ParseFile("config.yaml");
var server = (config as MappingNode).Nodes.Where(n => (n.Key as ScalarNode).Value == "server").Single().Value;
var address = ((server as MappingNode).Nodes.Where(n => (n.Key as ScalarNode).Value == "address").Single().Value as ScalarNode).Value;
var port = ((server as MappingNode).Nodes.Where(n => (n.Key as ScalarNode).Value == "port").Single().Value as ScalarNode).Value;
Console.WriteLine(address);
Console.WriteLine(port);
var persons = (config as MappingNode).Nodes.Where(n => (n.Key as ScalarNode).Value == "persons").Single().Value;
var person = (persons as SequenceNode).Nodes.Where(n =>{
var name = (n as MappingNode).Nodes.Where(n2 => (n2.Key as ScalarNode).Value == "name").Single().Value;
return (name as ScalarNode).Value == "丁一";
}).Single();
Console.WriteLine(((person as MappingNode).Nodes.Where(n => (n.Key as ScalarNode).Value == "name").Single().Value as ScalarNode).Value);
}
不要忘记了 生成以后YLab.YAML项目下的YLab.YAML文件夹要拷贝到生成exe的目录里面 ironruby的lib目录也拷贝进去改名为RubyLib 当然不需要的rb文件你可以去掉啦 只要留下和yaml相关的rb文件就可以了
源码:CSharp_Parse_Yaml_Via_IronRuby.rar
问题:win7+E文的vs 没问题 winXP + 中文的vs 出现问题
irb.GetRubyEngine().Execute(code);
作者: ThinkInSharp 发表于 2011-06-06 22:10 原文链接