我有以下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 class Item
{
[XmlIgnore()]
public int ItemIndex {get;set;}
public string Name {get;set;}
private Item[] itemsList;
[XmlElement(IsNullable = true)]
[XmlArrayItem("Item", typeof(Item))]
[XmlArray("ItemList")]
public Item[] ItemsList
{
get
{
return itemsList;
}
set
{
itemsList= value;
}
}
}
[XmlRoot("ItemsRoot")]
public class ItemsRoot
{
private Item[] itemsList;
[XmlArrayItem("Item", typeof(Item))]
[XmlArray("ItemList")]
public Item[] ItemsList
{
get
{
return itemsList;
}
set
{
itemsList= value;
}
}
}
反序列化代码:
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变量。
即。
名称为A的项目对象将为索引0
名称为B的Item对象将为索引1 等等
然后
项目AA将再次为索引0 项目AB将是索引1
等等
我不太关心何时填充ItemIndex。这可能发生在反序列化之后,我只是认为这是一个很好的做法。
答案 0 :(得分:0)
这应该可以解决问题 -
public class ItemsRoot
{
public List<Item> ItemList { get; set; }
}
public class Item
{
public string Name { get; set; }
public List<Item> ItemList { 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();
}
答案 1 :(得分:0)
以下是我将如何做到这一点的伪代码。
这里我从磁盘读取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;
}
}
}
}
}
然后,当您调用StreamXmlDoc方法时,您可以根据需要填充模型,如下面的示例所示。
var counter = 0;
var serializedObjects = XmlHelper.StreamXmlDoc(fs, NodeName);
foreach (var element in serializedObjects)
{
// Convert (Deserialize) the patient XElement to an instance of the DESPatientModel class.
var item = XmlHelper.XmlDeserialize(element.ToString(), typeof(YourType));
item.ItemIndex = counter++;
}
答案 2 :(得分:0)
我找到了一种方法来做到这一点。
在master
班级中我添加了以下内容:
Item
因此,在反序列化后,我有以下内容:
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();
}
}
}
它可以根据需要完成工作。
答案 3 :(得分:0)
如果仅在反序列化后访问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;
}
}
}
}
}
在更通用的情况下,考虑将{Parent}属性添加到Item
类并动态计算itemIndex。在这种情况下,您还需要定义自己的CollectionType: Collection<Item>
类型而不是Item[]