技术开发 频道

C#:用DynamicObject动态读取并操作XML

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result
= null;
        
if (binder.Name == "Value"
           result = _elements[0].Value;
        
else if (binder.Name == "Count")
            result
= _elements.Count;
        
else
        {
            var attr
= _elements[0].Attribute(
                XName.Get(binder.Name));
            
if (attr != null)
                result
= attr;
            
else
            {
                var items
= _elements.Descendants(
                    XName.Get(binder.Name));
                
if (items == null ||items.Count() == 0)                    return false;
                result
= new DynamicXml(items);
            }
        }
        
return true;
    }
    
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
    {
        
int ndx = (int)indexes[0];        result = new DynamicXml(_elements[ndx]);
        
return true;
    }
    
public IEnumerator GetEnumerator()
    {
        foreach (var element
in _elements)
            yield
return new DynamicXml(element);
    }
}

  运用

  在具体运用中, 有些地方是非常有趣的, 因为我们有了dynamic, 所以你可以用同一个变量去获取不同结构的XML文件. 运用代码如下:

static void Main(string[] args)
{
    
string xml = @"<root>
                     <books>
                        <book>
                            <author>John Savacki</author>
                           <title>E.G.Title</title>
                          <price>20.50</price>
                        </book>
                        <book>
                            <author>Tom Curly</author>
                           <title>E.G.Title 2</title>
                          <price>26.50</price>
                      </book>
                    </books>
                </root>
";    dynamic dx = new DynamicXml(xml);
    Console.WriteLine(
"----- Book List -----");
    
foreach (dynamic b in dx.books.book)
    {
        Console.WriteLine(
"author='{0}'", b.author.Value);
        print(b);
    }
    Console.WriteLine(
"------ Book List End ------");
    
string xml2 = @"<root>
                        <products>
                            <product>
                              <title>iPhone 4</title>
                              <price>2222.50</price>
                              <quantity>10</quantity>
                            </product>
                            <product>
                              <title>Lenovo IdeaPad</title>
                              <price>5432.50</price>
                              <quantity>15</quantity>
                           </product>
                        </products>
                    </root>
";
    dx
= new DynamicXml(xml2);
    Console.WriteLine(
"----- Product List -----");
    
foreach (dynamic b in dx.products.product)
    {
        Console.WriteLine(
"quantity='{0}'", b.quantity.Value);
        print(b);
    }
    Console.WriteLine(
"------ Product List End ------");
    Console.Read();
}

   我把print函数专门拿出来, 故弄玄虚一下, 因为两个XML的结构有类似的地方, 所以可以同时使用下面的函数. -- 当然对于这样的情况,我们也可以为此定义一个interface.

static void print(dynamic b)
 
 
    Console.WriteLine("Title='{0}'", b.title.Value);
    Console.WriteLine("price='{0}'", b.price.Value);
 }

   不是什么很深奥的东西, 但是希望可以为有同样问题的朋友们节省一些时间.

  如果可以较好的掌握Dynamic, 可以节省一些反射方面的代码

0
相关文章