【发布时间】:2017-03-29 20:25:42
【问题描述】:
我的总体目标是能够从我的 REST API 向 .NET 客户端返回 XML 响应。在我这样做之前,我需要了解如何对这些数据进行分类,以便客户能够理解它。我计划将 XML 反序列化为一个类对象。我目前正在使用 Cars 的示例。
我有以下 XML:
<?xml version="1.0" encoding="utf-8"?>
<CarCollection>
<Cars>
<Car>
<StockNumber>1020</StockNumber>
<Make>Nissan</Make>
<Model>Sentra</Model>
</Car>
<Car>
<StockNumber>1010</StockNumber>
<Make>Toyota</Make>
<Model>Corolla</Model>
</Car>
<Car>
<StockNumber>1111</StockNumber>
<Make>Honda</Make>
<Model>Accord</Model>
</Car>
</Cars>
</CarCollection>
我通过 XSD.exe 工具(使用上面的 xml 文件)生成了以下 XSD:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="CarCollection" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="CarCollection" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Cars">
<xs:complexType>
<xs:sequence>
<xs:element name="Car" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="StockNumber" type="xs:string" minOccurs="0" />
<xs:element name="Make" type="xs:string" minOccurs="0" />
<xs:element name="Model" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
由此,我生成了以下 C# 类(命令:xsd.exe carcollection.xsd /c):
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System.Xml.Serialization;
//
// This source code was auto-generated by xsd, Version=4.6.1586.0.
//
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1586.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class CarCollection {
private CarCollectionCars[] itemsField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Cars", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public CarCollectionCars[] Items {
get {
return this.itemsField;
}
set {
this.itemsField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1586.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class CarCollectionCars {
private CarCollectionCarsCar[] carField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Car", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public CarCollectionCarsCar[] Car {
get {
return this.carField;
}
set {
this.carField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1586.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class CarCollectionCarsCar {
private string stockNumberField;
private string makeField;
private string modelField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string StockNumber {
get {
return this.stockNumberField;
}
set {
this.stockNumberField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string Make {
get {
return this.makeField;
}
set {
this.makeField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string Model {
get {
return this.modelField;
}
set {
this.modelField = value;
}
}
}
我将上面的 XML 文件和 XSD 添加到我的项目中。这是我的主要课程:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.Reflection;
using System.Xml;
namespace xmlToClass
{
class Program
{
static void Main(string[] args)
{
XmlSerializer ser = new XmlSerializer(typeof(CarCollection));
CarCollection collection;
var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var file = dir + @"\test.xml";
using (XmlReader reader = XmlReader.Create(file))
{
collection = (CarCollection)ser.Deserialize(reader);
}
//I can access these directly
Console.WriteLine(collection.Car[0].StockNumber);
Console.WriteLine(collection.Car[1].StockNumber);
Console.WriteLine(collection.Car[2].StockNumber);
//TODO: How to iterate over this collection?
Console.ReadLine();
}
}
}
我希望能够迭代此集合并同时访问属性。我尝试了 foreach 循环,但控制台只打印了命名空间和对象名称"xmlToClass.CarCollection+CarsRow"(默认的 toString() 方法)。
foreach(var car in con.Cars)
{
Console.WriteLine(car);
}
我会使用 for 循环,但我无法获得集合的长度。我想我不理解生成的类属性或字段......我会非常感谢一些方向!奖励问题(在我了解如何正确访问这些被 XML 反序列化为类的对象之后):
- 如果我希望 StockNumber 为“int”或“integer”类型而不是字符串,该怎么办?我尝试向 XML 文档添加类型属性并重新生成 XSD,但无济于事。
感谢您的宝贵时间!如果你想要项目文件,我可以发给你。
注意事项
- 我不想直接编辑 XSD 或 .CS 文件,因为它们都是从 XML 文档生成的。需要对 XML 文档进行的任何更改都需要重新生成 XSD/CS 文件。
【问题讨论】: