Xml反序列化,在不同标签间执行命令

问题描述:

我有我需要用XmlSerializer反序列化的xml(我无法控制)。我的麻烦是我需要在一个列表中保存两个不同标签之间的顺序。让我举一个例子:Xml反序列化,在不同标签间执行命令

<users> 
    <luser>..some more elements..</luser> 
    <luser>..some more elements..</luser> 
    <admin>..different elements than in luser</admin> 
    <luser>..some more elements..</luser> 
    <admin>..different elements than in luser</admin> 
    <luser>..some more elements..</luser> 
    <admin>..different elements than in luser</admin> 
<users> 

现在,如果我deserialze这个直接的方式,我结束了两个列表,一个用于LUSERS,一个用于管理员。但是,它们出现的顺序是隐式ID! (当然应该已经在XML属性或元素,但可惜它不是)

我试图做一个meta元素这样

[XmlElement("luser"),XmlElement("admin")] 
public List<Person> Person { get; set; } 

public class Person 
{ 
    public Luser Luser { get; set; } 
    public Admin Admin { get; set; } 
} 

计划是检查列表以查看是否输入luser或管理员,并让人员包装维护元素的顺序。但是,单个属性上的多个XmlElement属性似乎是非法的。

另一个可以接受的解决方案是最终得到两个列表,但每个列表中的每个条目都有一个我可以用来获取原始顺序的ID。

我希望这个尽可能干净。之后搜索xml以查找订单,手动提取标签以及类似内容,这是我会避免的,并且是最后一招。

+0

我知道它并不能真正帮助你,但它似乎很愚蠢,你需要让它们保持秩序。显然似乎没有任何模式来规定这种安排。你为什么不能让所有的用户跟随所有的管理员?这是你的系统强加的约束,还是其他一方要求你不要改变列表?也看看这个,它可能会给你一些想法:http://*.com/questions/1007626/in-net-xml-deserialization-how-can-i-allow-polymorphic-use-of-array-类型 – Thomas 2012-04-26 14:50:10

+0

第一个条目(用户或管理员)是id 1,下一个是id 2(无论是用户还是管理员)等等。是的,这很愚蠢,但我无能为力。我会查看链接,谢谢 – Toodleey 2012-04-26 15:16:19

+0

Ew,userIds是基于XML文档中的位置?这太可怕了。我想这是不可能的,以使得userId是一个属性? – Thomas 2012-04-26 15:19:59

这当然应该是一个属性...

然后只要你可以把它的属性。然后处理结果。

var doc = XDocument.Load(...); 

var fixeruppers = doc 
     .Descendants("users") 
     .Elements() 
     .ToList(); // isolate us from any movements in the doc 

int id = 1; // base 
foreach (var fixer in fixeruppers) 
    fixer.SetAttributeValue("Id", id++); 

XmlReader readerForDeserialize = doc.CreateReader(); 
+0

+1。订单不被保留的原因是XML中没有这样的订单 - 你需要一个,你有一个。谁做错了谁是可以回避的 - 没有办法解决这个问题。添加一个ID。 – TomTom 2012-04-26 15:00:36

+0

多数民众赞成这是目前为止最干净的方式,虽然它感觉有点哈克它肯定会反序列化整个手动或其他事情已经跨过我的脑海 – Toodleey 2012-04-26 15:17:54

+1

主要观点是要做到这一点,并跨越你的手指。大多数XML工具/解析器都不会觉得有义务维护任何'订单'。还要注意XDocument.CreateReader(),你可以连接大多数的反序列化器。 – 2012-04-26 15:52:24

以下内容将规定顺序(顺序为:=值),但不会改变类的序列化方式。

Imports System.Runtime.Serialization 
Imports System.ServiceModel 

<DataContract()> _ 
Public Class MyClass 

    <DataMember(order:=1)> _ 
    Public Property SomeData() As String 

    <DataMember(order:=2)> _ 
    Public Property SomeOtherData() As String 

End Class