【问题标题】:LINQ to XML to POCO objectLINQ to XML to POCO 对象
【发布时间】:2010-08-20 14:01:23
【问题描述】:

我有一个 XML 文件,我想将其转换为 POCO 对象列表。

我有以下工作代码来读取 XML 并从中创建对象。我只是想检查一下这是一个很好的方法,而且我没有错过任何技巧。特别是关于嵌套的 Linq 查询。

XDocument xmlDoc = XDocument.Load(path);
var q = from file in xmlDoc.Descendants("File")
        select new ImportDefinition()
        {
            Name = file.Attribute("Name").Value,
            TypeName = file.Attribute("TypeName").Value,
            ColumnMappings =  
            (
                from map in file.Descendants("ColumnMap") 
                select new ColumnMap() 
                { 
                    DatabaseColumn = new Column()
                    { 
                        Name = map.Element("DatabaseColumn").Attribute("Name").Value
                    }
                }
            ).ToList<ColumnMap>()               
        };
List<ImportDefinition> def = q.ToList<ImportDefinition>();

谢谢

【问题讨论】:

    标签: c# linq-to-xml poco


    【解决方案1】:

    也许尝试显式转换

    public class ColumnMap
    {
        public static explicit operator ColumnMap(XElement xElem)
        {
            return new ColumnMap()
            {
                DatabaseColumn = new Column()
                {
                    Name = xElem.Element("DatabaseColumn").Attribute("Name").Value
                }
            };
        }
    }
    
    public class ImportDefinition
    {
        public static explicit operator ImportDefinition(XElement xElem)
        {
            return new ImportDefinition() 
            { 
                Name           = (string)xElem.Attribute("Name"), 
                TypeName       = (string)xElem.Attribute("TypeName"), 
                Size           = (int)xElem.Attribute("Size"), 
                LastModified   = (DateTime?)xElem.Attribute("LastModified"), 
                ColumnMappings = xElem.Descendants("ColumnMap").Select(xelem => (ColumnMap)xelem).ToList()
            }; 
        }
    }
    

    然后像这样使用它:

    XDocument xmlDoc = XDocument.Load(path); 
    List<ImportDefinition> importDefinitions = xmlDoc.Descendants("File").Select(xElem => (ImportDefinition)xElem).ToList()
    

    【讨论】:

    • Afaik .Cast 不调用自定义转换运算符 - 或者是吗?
    • @dtb:如果不是,那么这将行不通。尚未测试,但会认为它只是一个扩展,它执行类似 IEnumerable Cast(IEnumerable targets) { foreach(T target in targets) yield return (U)target; }
    • 我相信这正是 Enumerable.Cast 所做的,并且由于转换为通用参数 U 而可能无法正常工作,而 afaik 不寻找自定义转换运算符。但我也没有测试过。
    • @dtb: 咬紧牙关并给它一个测试,你是对的,它没有寻找自定义转换运算符,尽管 select 方法工作得很好。奇怪,不会想到通用间接会这样做..
    【解决方案2】:

    如果您的 POCO 对象不仅具有字符串属性,XElement 和 XAttribute 为其他类型提供了广泛的 conversion operators 选择,包括在元素/属性不存在的情况下可为空。

    例子:

    XDocument xmlDoc = XDocument.Load(path);
    var q = from file in xmlDoc.Descendants("File")
            select new ImportDefinition()
            {
                Name         = (string)file.Attribute("Name"),
                TypeName     = (string)file.Attribute("TypeName"),
                Size         = (int)file.Attribute("Size"),
                LastModified = (DateTime?)file.Attribute("LastModified"),
                // ...
            };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多