使用ExpandoObject将XML转换为动态对象_XML怎么转对象
2014-08-12 13:14:48  By: dwtedx

简介

我一直在网上找XML的读取方法,并把它转换为一个对象

我的目的是动态加载XML文、并转换成对象

由于每个XML定义模式都截然不同、我想用dynamic关键字来加载XML文档,并访问它作为一个简单的对象

查阅了一些资料后,我发现了一些例子,所使用的都是ExpandoObject

不幸的是,他们要么写一个对象转换为XML或如何使用XML到LINQ的映射一个特定的动态类/对象

所以,我最后写加载XML文档,并把它转换成一个简单的对象小递归方法

话不多说、直接上代码

private static dynamic _getExpandoFromXml(String file, XElement node = null)
{
    if (String.IsNullOrWhiteSpace(file) && node == null) return null;
    // If a file is not empty then load the xml and overwrite node with the
    // root element of the loaded document
    if (!String.IsNullOrWhiteSpace(file))
    {
        var doc = XDocument.Load(file);
        node = doc.Root;
    }
    dynamic result = new ExpandoObject();
    var pluralizationService = System.Data.Entity.Design.PluralizationServices.
    PluralizationService.CreateService(CultureInfo.CurrentCulture);
    foreach (var gn in node.Elements())
    {
        // The code determines if it is a container node based on the child
        // elements with the same name. If there is only one child element,
        // then it uses the PluralizationService to determine if the 
		//pluralization of the child elements name 
        // matches the parent node. If so then it´s most likely a collection 
        var isCollection = gn.HasElements &&
            ( 
                gn.Elements().Count() > 1 && gn.Elements().All
                (e => e.Name.LocalName.ToLower() == gn.Elements()
				.First().Name.LocalName) ||
                gn.Name.LocalName.ToLower() == pluralizationService.Pluralize
                (gn.Elements().First().Name.LocalName).ToLower()
            );
                    
        var p = result as IDictionary<String, dynamic>;
        var values = new List<dynamic>();
        // If the current node is a container node then we want to skip adding
        // the container node itself, but instead we load the children elements
        // of the current node. If the current node has child elements then load
        // those child elements recursively
        if (isCollection)
            foreach (var item in gn.Elements())
            {
                values.Add((item.HasElements) ? _getExpandoFromXml(null, item) :
                    item.Value.Trim());
            }
        else
            values.Add((gn.HasElements) ? _getExpandoFromXml(null, gn) :
                gn.Value.Trim());

        // Add the object name + value or value collection to the dictionary
        p[gn.Name.LocalName] = isCollection ? values : values.FirstOrDefault();
    }
    return result;
}


示例XML

<?xml version="1.0"?>
 <License>
    <RegisteredUser>Remco Reitsma</RegisteredUser>
    <Company>Xtraworks.com</Company>
    <Sites>
        <Site>
            <Host>xtraworks.com</Host>
            <ExpireDate>15/12/2099</ExpireDate>
        </Site>
        <Site>
            <Host>test.com</Host>
            <ExpireDate>15/12/2099</ExpireDate>
        </Site>
    </Sites>
    <Modules>
        <Module>
            <Name>SEO Package</Name>
            <Controller>SEO</Controller>
            <Version>0.0.1</Version>
            <Tables>
                <Table>
                    <Name>SEO_Site</Name>
                </Table>
                <Table>
                    <Name>SEO_Pages</Name>
                </Table>
            </Tables>
        </Module>
    </Modules>
</License>


使用示例

dynamic license = _getExpandoFromXml(´path to xml file´);
    
// Getting the values from the dynamic object is really easy now.
var registeredUser = license.RegisteredUser;
var companyName = license.Company;

// Getting a collection is just as easy as it simply returns a list
var sites = license.Sites;
foreach(var site in sites)
{ 
   var host = site.Host;
}


好了、到这里就可读取一个简单的XML了、希望对大家有帮助

若资源对你有帮助、浏览后有很大收获、不妨小额打赏我一下、你的鼓励是维持我不断写博客最大动力

想获取DD博客最新代码、你可以扫描下方的二维码、关注DD博客微信公众号(ddblogs)

或者你也可以关注我的新浪微博、了解DD博客的最新动态:DD博客官方微博(dwtedx的微博)

如对资源有任何疑问或觉得仍然有很大的改善空间、可以对该博文进行评论、希望不吝赐教

为保证及时回复、可以使用博客留言板给我留言: DD博客留言板(dwtedx的留言板)

感谢你的访问、祝你生活愉快、工作顺心、欢迎常来逛逛


快速评论


技术评论

  • 该技术还没有评论、赶快抢沙发吧...
DD记账
top
+