yaml模板,C#通过IronRuby分析YAML

Yaml是一种不错的格式,无论是作为配置文件还是小量数据的存储都是一种不错的选择。ruby和它结合的比较好,但是其它语言,目前的parser还不完善。
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
然后是YAML.cs文件
1 using System; 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 searchPath = new List(); 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
server: address: 10.0.0.86 port: 36 persons: - name: 丁一 age: 30 - name: 王二 age: 33
然后是program.cs
static void Main(string[] args) { 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);
character U+901A can't be encoded in US-ASCII
Tags:  新建yaml文件 yaml模板

延伸阅读

最新评论

发表评论