2012-05-29 40 views
1

我有一些xml提供了通用属性(名称,类型等),其中属性的值需要是xml反序列化的属性。使用通用XML属性进行反序列化

XML的我试图推到一个类将是类型的样本:

<root> 
    <company> 
     <location>USA</location> 
     <name>TopCars</name> 
    </company> 
    <CarList name="CarCounts"> 
     <ModelList name="Models"> 
      <Column name="Ford">50</Column> 
      <Column name="Chevy">65</Column> 
      <Column name="Dodge">75</Column> 
     </ModelList> 
    </CarList> 
</root> 

我可以提供我用一些示例代码,但它不工作,我喜欢一些新鲜的观点。我正在使用一个由具有由属性“name”标识的单个属性的类反序列化的xmlReader,这不是我想要的。我最终想要包含福特,雪佛兰和道奇属性的类模型(如果您反对这里的汽车结构,这是一个制作的例子)。

XSD吐出了这样的事情是什么样的我所期望的,但不是真的是我想要的:

[...] 
<xs:element name="Column" nillable="true" minOccurs="0" maxOccurs="unbounded"> 
    <xs:complexType> 
    <xs:simpleContent msdata:ColumnName="Column_Text" msdata:Ordinal="1"> 
     <xs:extension base="xs:string"> 
     <xs:attribute name="name" type="xs:string" /> 
     </xs:extension> 
    </xs:simpleContent> 
    </xs:complexType> 
</xs:element> 
[...] 

我不通过这种技术的限制。我正在用C#开发。

任何帮助表示赞赏。

@RichardTowers:我尝试了以下列出的XML,并收到错误“XML文档(1,2)中存在错误”。

Base.Root[] cars = null; 
XmlSerializer serializer = new XmlSerializer(typeof(Base.Root[])); 
XmlReader reader = XmlReader.Create(new StringReader(xml)); 
cars = (Base.Root[])serializer.Deserialize(reader); 
reader.Close(); 

我试图改变你xmlElementAttribute装饰建议类,添加“”到的xmlString的开始。我也尝试用StreamReader切换StringReader无济于事。还有其他建议吗?

+0

您的控件是XML格式还是使用外部源的XML? – gilly3

+0

xml完全不在我的控制范围之内。 – John

+0

我已经添加了一个关于如何做到这一点的例子。你会注意到它有点噩梦。这是因为你的XML看起来不像你想要表示的数据。 – RichardTowers

回答

2

你想要做的不是真正的反序列化工作。一方面你有一些XML,另一方面是C#类。他们需要看起来像对方的串行器来完成其工作。

你说你想要一个像类:

class Models 
{ 
    int Chevy { get; set; } //65 
    int Dodge { get; set; } //75 
} 

首先,我不认为它能够系列化你的XML弄成这个样子。但即使是这样,如果你的XML代替了Mercedes,会发生什么呢?你不能反序列化那一点,因为它不在你的课堂上。

基本上你的类需要模仿你的XML。你想要的东西,如:

class Root 
{ 
    Company Company { get; set; } 
    List<Model> ModelList { get; set; } 
} 

class Company 
{ 
    string Location { get; set; } 
    string Name { get; set; } 
} 

class Model 
{ 
    string Name { get; set; } 
    int Value { get; set; } 
} 

然后,您可以通过执行类似引用您的机型:

// Get the value for Chevy: 
root.ModelList.Find(model => model.Name == "Chevy").Value; 

编辑:这里的一切要做到这一点所需的代码的贴:http://pastebin.com/Z3b3558Z。对于缩进感到抱歉,VisualStudio有点兴奋。

+0

我很感激。松散地说,我想要做的是将这些数据序列化成一个类。如果元素被添加,我完全理解你的意思。有大量这些列元素,它们不会改变,但是在我的场景中,这些列名称可能是下一个全面的鸟类列表,用于不同的调用,并且我将为它创建一个自定义类以及。我想要一个更通用的中间人将xml加载到类中,即使这些类是紧密耦合的。我宁愿这样做,比我的代码期望像linq例子那样的元素。 – John

+1

那么你可以反序列化XML,就像我上面所描述的那样,然后有另一个类来封装我的例子中的Find代码(这不是By的linq)。 – RichardTowers

+0

感谢您的回复。我已经更新了我的问题,其中包括一些我最初尝试过的建议。如果你可以看看,我会很感激。 – John