原贴子:http://topic.csdn.net/u/20110213/17/ca32f50f-5f2b-4ca5-aefe-a0f9168b31af.html
需求是在以下的配置中,读取节点:ClassDemoCollection,再把它反序列化成集合类ClassDemoCollection,
最好用Linq to xml实现.
其中ClassDemoCollection是一个可序列化的集合类,详细的可以查看前一贴子.
想不出有什么好的方法处理,拜谢各位.若可以话请试验过后再回贴,
解决了的也请到前一个贴子留名,好贴给分,谢谢!<?xml version="1.0" encoding="utf-8" ?>
<Root>
<A>asdasd</A>
<B value="1">445</B>
<ClassDemoCollection>
      <item>
          <ItemId>1</ItemId>
          <ItemName>test</ItemName>
      </item>
      <item>
          <ItemId>2</ItemId>
          <ItemName>test</ItemName>
      </item>
</ClassDemoCollection>
</Root>

解决方案 »

  1.   

    读取XML
    string xml = @"";
    XElement xmlPage = XElement.Parse(xml);   
      var query = xmlPage.Descendants("").Select(x=>x.Element("").Value)
        
     
      

  2.   

    http://topic.csdn.net/u/20110126/14/649b38da-6453-4b64-a4d9-dbda76a62810.html
      

  3.   

    谢谢~~我已经把需要的节点获取到了(得到了一个XElement 对象)
    现在是如何在内存里把XElement 对象反序列化为ClassDemoCollection这个类
    和xml反序列化为类是一样,但找不知道如何单个反序列化XElement .曾经想过用反射,
    但由于ClassDemoCollection包含了多个索引成员,也不行...
      

  4.   

    试过以下几种方法,都不可行:
    1. 把XElement直接能转为xml字符串,再加上xml标准声明,装进 StringReader后使用XmlSerializer直接把字符串反序列化.
    2. 装进XDocument加入xml标准声明后反序列化,也不行
    3. 反射ClassDemoCollection再读取XElement的节点后逐个赋值,不可行.这样子得到的只是ClassDemoCollection本身的type,而实际要赋值的应该是它的成员属性================================================================>
      

  5.   

    楼主,你这个ConfigItem是什么东西
      

  6.   

    原贴中[Serializable]
        public class ClassDemoCollection: CollectionBaseCommon<Item>
        {
            public ConfigItem GetItem(Item model)
            {
                if (this.List.Count > 0)
                {
                    foreach (Item item in this.List)
                    {
                        if (model == item)
                            return item;
                    }
                }
                return null;
            }
        }ConfigItem是Item的一个派生类,由于整个其他的代码较长,所以没能全贴出来,不好意思.
    你可以把上面的类看成[Serializable]
        public class ClassDemoCollection: CollectionBaseCommon<Item>
        {
            
        }就行了,能从XElement中反序列化ClassDemoCollection就可以了
      

  7.   

     你这样的XML结构是无法做反序列化的,先做一下修改<?xml version="1.0" encoding="utf-8" ?>
    <Root>
    <A>asdasd</A>
    <B value="1">445</B>
    <ClassDemoCollection>
      <Items>
          <Item>
              <ItemId>1</ItemId>
              <ItemName>test</ItemName>
          </Item>
          <Item>
              <ItemId>2</ItemId>
              <ItemName>test</ItemName>
          </Item>
       </Items>
    </ClassDemoCollection>
    </Root>加Items节点,用来对应List另外有List<T>可用,何必再实现CollectionBaseCommon<T>,
    我想你的实现没有MS做的好吧.ClassDemoCollection 做以下修改: [Serializable]
        public class ClassDemoCollection 
        {
            public Item GetItem(Item model)
            {
                if (Items != null && Items.Count > 0)
                {
                    foreach (Item item in Items)
                    {
                        if (model == item)
                            return item;
                    }
                }
                return null;
            }         [XmlArray("Items"),
             XmlArrayItem("Item", typeof(Item))]
            public List<Item> Items { get; set; }
        }   关键的几个xml属性,这是必须要指定的   [XmlArray("Items"),
       XmlArrayItem("Item", typeof(Item))]   反序列化操作代码:   var  doc = new XmlDocument();
                doc.Load(@"c:\1.xml");
                var node = doc.DocumentElement.SelectSingleNode("ClassDemoCollection");
                var reader = new XmlTextReader(node.OuterXml,XmlNodeType.Element,null);          var serializer = new XmlSerializer(typeof(ClassDemoCollection));
              ClassDemoCollection objToDeserialize = serializer.Deserialize(reader) as ClassDemoCollection;
      

  8.   


    List<Item> itemList=new List<Item>();
    XmlDocument doc = new XmlDocument();
    doc.LoadXml(xml);
    XmlNodeList itemNodes = doc.SelectNodes("/Root/ClassDemoCollection");
    foreach (XmlNode itemNode in itemNodes)
    {
    Item item=new Item();XmlNode itemIdNode= itemNode.SelectSingleNode("ItemId");
    item.ItemId=itemIdNode.InnerText;
    XmlNode itemNameNode= itemNode.SelectSingleNode("ItemName");
    item.ItemName=itemNameNode.InnerText;
    itemList.Add(item);
    }
      

  9.   

    加一句,如果是Items同时包含Item的子类,如ConfigItem
    则改成 [XmlArray("Items"),
       XmlArrayItem("Item", typeof(ConfigItem)),
       XmlArrayItem("ConfigItem", typeof(ConfigItem)),]
       也就是说,你用来做反序列化的xml输入,
       实际是需要根据Item类型来指定相应节点,
       如果是Item和ConfigItem混合,则需要是<Items>
          <Item>
              <ItemId>2</ItemId>
              <ItemName>test</ItemName>
          </Item>
          <ConfigItem>
              <ItemId>2</ItemId>
              <ItemName>test</ItemName>
          </ConfigItem>
    </Items>
      

  10.   

    既然ConfigItem是Item的一个派生类,我就返回Item吧
    下面是你的原代码    [Serializable()]
        public class CollectionBaseCommon<T> : CollectionBase where T : class
        {
            /// <summary>
            /// 成员索引
            /// </summary>
            /// <param name="index"></param>
            /// <returns></returns>
            public T this[int index]
            {
                get
                {
                    return ( this.List[index] ) as T;
                }
                set
                {
                    this.List[index] = value;
                }
            }        /// <summary>
            /// 添加一个成员
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public int Add( T model )
            {
                return this.List.Add( model );
            }        /// <summary>
            /// 移除一个成员
            /// </summary>
            /// <param name="model"></param>
            public void Remove( T model )
            {
                this.List.Remove( model );
            }
        }    [Serializable]
        public class Item
        {
            public int ItemId
            {
                get;
                set;
            }        public string ItemName
            {
                get;
                set;
            }
        }    [Serializable]
        public class ClassDemoCollection : CollectionBaseCommon<Item>
        {
            //此处由 ConfigItem 改成 Item
            public Item GetItem( Item model )
            {
                if ( this.List.Count > 0 )
                {
                    foreach ( Item item in this.List )
                    {
                        if ( model == item )
                            return item;
                    }
                }
                return null;
            }
        }
    下面是读取的代码
            private static void Test()
            {
                ClassDemoCollection c = new ClassDemoCollection();            var a = from item in XElement.Load( "d:\\ttt.xml" ).Descendants( "item" )
                        select new
                        {
                            ItemId = int.Parse( item.Element( "ItemId" ).Value ),
                            ItemName = item.Element( "ItemName" ).Value
                        };            foreach ( var item in a )
                {
                    c.Add( new Item()
                    {
                        ItemId = item.ItemId,
                        ItemName = item.ItemName
                    } );
                }
            }
    环境:OS XpSp3
         .Net FrameWork4.0
         C# 4.0
      

  11.   

    啊,,也是啊..我困死自己了,其实xml本身就是一种数据的的表现形式,直接操作也是可以了..哎~~,谢谢,
    两位的解决方案都是可行的,,茅塞顿开,一开始我就拘泥地以为只有序列化这种方式可以处理了.
    不过对序列化理解也很肤浅,受教了~~~晚上结贴,请也到旧贴留个名好给分,谢谢~