Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将列表集索引反序列化为对象属性_C#_Xml - Fatal编程技术网

C# 将列表集索引反序列化为对象属性

C# 将列表集索引反序列化为对象属性,c#,xml,C#,Xml,我有以下XML <ItemsRoot> <ItemList> <Item> <Name>A</Name> <ItemList> <Item> <Name>AA</Name> </Item>

我有以下XML

<ItemsRoot>
     <ItemList>
         <Item>
             <Name>A</Name>
             <ItemList>
                 <Item>
                    <Name>AA</Name>
                 </Item>
                 <Item>
                    <Name>AB</Name>
                 </Item>
             </ItemList>
         </Item>
         <Item>
             <Name>B</Name>
         </Item>
         <Item>
             <Name>C</Name>
         </Item>
     </ItemList>
</ItemsRoot>
反序列化代码:

public static object XmlDeserialize(string dataXML, Type objectType)
{
    XmlDocument xDoc = new XmlDocument();
    xDoc.LoadXml(dataXML);
    XmlNodeReader xNodeReader = new XmlNodeReader(xDoc.DocumentElement);
    XmlSerializer xmlSerializer = new XmlSerializer(objectType);
    var objectData = xmlSerializer.Deserialize(xNodeReader);

    return objectData;
}
所以我要做的是,当我反序列化xml时,我想用列表中对象的索引填充ItemIndex变量

i、 e

名为A的项对象将成为索引0
名为B的项对象将成为索引1 等

然后

AA项将再次成为索引0
AB项将是索引1


我不太关心ItemIndex何时填充。这可能发生在反序列化之后,我只是觉得这是一个好地方

这应该可以解决问题-

public class ItemsRoot
{
    public List<Item> ItemList { get; set; }
}

public class Item
{
    public string Name { get; set; }
    public List<Item> ItemList { get; set; }
}
public类ItemsRoot
{
公共列表项列表{get;set;}
}
公共类项目
{
公共字符串名称{get;set;}
公共列表项列表{get;set;}
}
更新

var s = "<ItemsRoot><ItemList><Item><Name>A</Name><ItemList><Item><Name>AA</Name><ItemList><Item><Name>AAA</Name><ItemList><Item><Name>AAAA</Name><ItemList><Item><Name>AAAAA</Name></Item><Item><Name>ABBBB</Name></Item></ItemList></Item><Item><Name>ABBB</Name></Item></ItemList></Item><Item><Name>ABB</Name></Item></ItemList></Item><Item><Name>AB</Name></Item></ItemList></Item><Item><Name>B</Name></Item></ItemList></ItemsRoot>";

var type = new XmlSerializer(typeof(ItemsRoot));

var obj = type.Deserialize(new MemoryStream(Encoding.UTF8.GetBytes(s.ToCharArray())));

var reflectedType = ((ItemsRoot)obj).ItemList.Select((item, index) => new Item
        {
            Index = index,
            ItemList = Find(item),
            Name = item.Name
        });

static List<Item> Find(Item item)
{
        return item.ItemList.Select((j, k) => new Item
    {
     Name = j.Name,
     ItemList = Find(j),//j.ItemList,
     Index = k//Find(item.ItemList, j)
    }).ToList();
}
var s=“aaaaaaaaaaaaaaaaaabbbbbbbabb”;
var type=新的XmlSerializer(typeof(ItemsRoot));
var obj=type.Deserialize(新的MemoryStream(Encoding.UTF8.GetBytes(s.tocharray()));
var reflectedType=((ItemsRoot)obj).ItemList.Select((项目,索引)=>新项目
{
索引=索引,
ItemList=查找(项目),
Name=项目名称
});
静态列表查找(项)
{
return item.ItemList.选择((j,k)=>new item
{
Name=j.Name,
ItemList=Find(j),//j.ItemList,
Index=k//Find(item.ItemList,j)
}).ToList();
}

以下是一些关于我将如何做到这一点的伪代码

这里我从磁盘读取Xml文件

public static IEnumerable<XElement> StreamXmlDoc(Stream inputStream, string nodeName)
{
    using (var reader = new StreamReader(inputStream))
    {
        using (var xmlReader = XmlReader.Create(reader))
        {
            xmlReader.MoveToContent();

            while (xmlReader.Read())
            {
                switch (xmlReader.NodeType)
                {
                    case XmlNodeType.Element:
                        if (xmlReader.Name == nodeName)
                        {
                            var xElement = XElement.ReadFrom(xmlReader) as XElement;

                            if (xElement != null)
                            {
                                yield return xElement;
                            }
                        }
                        break;
                }

            }
        }
    }
}

我已经找到了一种方法

项目中
I类增加了以下内容:

public class Item
{
.
.
.
    //method that will set the ItemIndex to the current index
    public void UpdateIndex(int index)
    {
        this.ItemIndex = index;
        if (this.ItemsList != null)
        {
            this.ItemsList = this.ItemsList.Select((x,index) => x.UpdateIndex(index+1)).ToList();
        }
    }   
}
ItemsRoot root = (ItemsRoot)CustomSerializer.XmlDeserialize(xmlText, typeof(ItemsRoot));
//now using linq 
root.ItemsList = root.ItemsList.ToList().Select((x,index) =>x.UpdateIndex(index+1))).ToArray();
因此,在反序列化之后,我有以下内容:

public class Item
{
.
.
.
    //method that will set the ItemIndex to the current index
    public void UpdateIndex(int index)
    {
        this.ItemIndex = index;
        if (this.ItemsList != null)
        {
            this.ItemsList = this.ItemsList.Select((x,index) => x.UpdateIndex(index+1)).ToList();
        }
    }   
}
ItemsRoot root = (ItemsRoot)CustomSerializer.XmlDeserialize(xmlText, typeof(ItemsRoot));
//now using linq 
root.ItemsList = root.ItemsList.ToList().Select((x,index) =>x.UpdateIndex(index+1))).ToArray();

它会根据需要执行此操作。

如果仅在反序列化后访问
ItemIndex
属性,则此操作将起作用:

public class Item 
{
    [XmlIgnore()]
    public int ItemIndex {get;set;}
    ...
    public Item[] ItemsList
    {
       get
       {
          return itemsList;
       }
      set
       {
           itemsList = value;
           if (itemsList != null)
           {
                for(int i = 0; i < itemsList.Length; ++i)
                {
                   itemsList[i].ItemIndex = i;
                }   
           }
       }
   }


 }
公共类项目
{
[XmlIgnore()]
公共int ItemIndex{get;set;}
...
公共项目[]项目列表
{
得到
{
返回项目列表;
}
设置
{
itemsList=值;
if(itemsList!=null)
{
对于(int i=0;i

在更一般的情况下,考虑将父属性添加到<代码>项目类,并即时计算ItEnt指标。在这种情况下,您还需要定义自己的

CollectionType:Collection
type,而不是
Item[]

反序列化的代码在哪里?你有什么错误吗?我已经添加了反序列化代码。没有错误。我只需要用数组中的索引填充ItemIndex变量。您想在反序列化时自动初始化ItemIndex,这可能不可能\困难。您可以编写方法,该方法将遍历项目列表并初始化每个项目的项目索引。在ItemsRoot classIs中的ItemList集合属性中调用该方法反序列化后是否更容易执行?当它完成时,我并不觉得太麻烦。@user3322417 XML本身的格式不好。元素类型“ItemList”必须由匹配的结束标记“”终止。什么是
NodeName
它是
ItemList
?ItemList。但是您的代码和Xml可能不需要在我给出的示例中开箱即用。如果你愿意的话,我可以给你一个大致可行的样本。它似乎不起作用。它从未使用AA循环过我的第二个列表,ABI从未看到您的列表项中嵌套了ItemList,而ItemList中包含了ItemList。一旦您反序列化了根ItemList,您的代码中将包含该对象,并且可以访问内部ItemList。谢谢,amit,但这并不能解决我的问题。我需要填充我的对象的ItemIndex属性,而您的答案没有这样做。您希望
ItemIndex
用于
AA
的是什么?我已经解决了我的问题,并提供了答案。谢谢你的帮助