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 < 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

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

 注: 上面这个问题我找到为什么了,包含我的程序的文件夹路径中只要包含有中文就会有这个问题,这个应该是IronRuby的问题了。

 

 

 

转载于:https://www.cnblogs.com/yuyingjian/archive/2011/06/06/2073910.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值