C#Deseralize - XML文档中存在错误(0,0)

时间:2016-01-21 18:13:08

标签: c# xml linq

我正在尝试对XDocumnet进行Deseralize并收到错误:“XML Documnet(0,0)中存在错误。”

XML:

<Machine>
  <Asset>
    <Product>COMPELLENT SC8000,1st,2nd,UPG</Product>
    <OrderNumber>12345678</OrderNumber>
    <ServiceTag>1234567</ServiceTag>
    <ShipDate>2014-02-07T00:00:00</ShipDate>
    <Warranties>
      <Warranty Services="4 Hour On-Site Service">
        <Service>
          <ServiceDescription>4 Hour On-Site Service</ServiceDescription>
          <Provider>UNY</Provider>
          <StartDate>2015-07-31T00:00:00</StartDate>
          <EndDate>2016-07-31T23:59:59</EndDate>
          <Type>EXTENDED</Type>
        </Service>
      </Warranty>
      <Warranty Services="CML - Storage Center Core Base">
        <Service>
          <ServiceDescription>CML - Storage Center Core Base</ServiceDescription>
          <Provider>DELL</Provider>
          <StartDate>2015-07-31T00:00:00</StartDate>
          <EndDate>2016-07-31T23:59:59</EndDate>
          <Type>EXTENDED</Type>
        </Service>
      </Warranty>
      <Warranty Services="Silver Premium Support">
        <Service>
          <ServiceDescription>Silver Premium Support</ServiceDescription>
          <Provider>DELL</Provider>
          <StartDate>2015-07-31T00:00:00</StartDate>
          <EndDate>2016-07-31T23:59:59</EndDate>
          <Type>EXTENDED</Type>
        </Service>
      </Warranty>
    </Warranties>
  </Asset>
</Machine>

类:

  public class Service
    {
        [XmlElement("ServiceDescription")]
        public string ServiceDescription { get; set; }
        [XmlElement("Provider")]
        public string Provider { get; set; }
        [XmlElement("StartDate")]
        public string StartDate { get; set; }
        [XmlElement("EndDate")]
        public string EndDate { get; set; }

    }
    [XmlType("Warranty")]
    public class Warranty
    {        
        [XmlElement("Service")]
        public Service objWarranty = new Service();

        [XmlAttribute("Services")]
        public string Services {get; set;}
    }
    public class Asset
    {
        [XmlElement("Product")]
        public string Product { get; set; }
        [XmlElement("OrderNumber")]
        public string OrderNumber { get; set; }
        [XmlElement("ServiceTag")]
        public string ServiceTag { get; set; }
        [XmlElement("ShipDate")]
        public string ShipDate { get; set; }
        [XmlArray("Warranties")]
        public List<Warranty> objWarrantyList = new List<Warranty>();
    }

功能: - 失败错误

private static void XlDesc(XDocument doc)
        {
            XmlSerializer deserializer = new XmlSerializer(typeof(List<Asset>));
            List<Asset> assetlist = (List<Asset>)deserializer.Deserialize(doc.Root.CreateReader());
            foreach (var info in assetlist)
            {
                //ToDo
            }

        }

可能有更好的方法。我很擅长使用Linq和xml文件。此XML是从现有XML文件

创建的

例如:

 var groupByWarrany = xlWarranty.GroupBy(x => x.Service);

                var newDocument = new XDocument(new XElement("Machine", xlBaseInfo.Select(z =>
                    new XElement("Asset",
                        new XElement("Product", z.Product),
                        new XElement("OrderNumber", z.OrderNumber),
                        new XElement("ServiceTag", z.ServiceTag),
                        new XElement("ShipDate", z.ShipDate),
                            (new XElement("Warranties", groupByWarrany.Select(x =>
                                new XElement("Warranty", new XAttribute("Services", x.Key),
                                x.Select(y => new XElement("Service",   
                                new XElement("ServiceDescription", y.Service),
                                new XElement("Provider", y.Provider),
                                new XElement("StartDate", y.StartDate),
                                new XElement("EndDate", y.EndDate),
                                new XElement("Type", y.TypeOfWarranty)
                        )).FirstOrDefault()
                        ))))))));

我想也许我可以跳过整个deseralize并在创建新XDoc时使用这些类。

2 个答案:

答案 0 :(得分:0)

测试电话:

XmlSerializer serializer = new XmlSerializer(typeof(Machine));
using (System.IO.FileStream stream = new System.IO.FileStream(@"C:\Users\Administrator\Desktop\test.xml", System.IO.FileMode.Open))
{
     Machine machine = (Machine)serializer.Deserialize(stream);
     // do stuff with machine
}

xml文档的类

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class Machine
{        /// <remarks/>
    public MachineAsset Asset { get; set; }
}

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class MachineAsset
{
    public string Product { get; set; }

    public uint OrderNumber { get; set; }

    public uint ServiceTag { get; set; }

    public System.DateTime ShipDate { get; set; }

    [System.Xml.Serialization.XmlArrayItemAttribute("Warranty", IsNullable = false)]
    public MachineAssetWarranty[] Warranties { get; set; }
}

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class MachineAssetWarranty
{
    public MachineAssetWarrantyService Service { get; set; }

    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Services { get; set; }
}

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class MachineAssetWarrantyService
{
    public string ServiceDescription { get; set; }

    public string Provider { get; set; }

    public System.DateTime StartDate { get; set; }

    public System.DateTime EndDate { get; set; }

    public string Type { get; set; }
}

如果您仍然遇到奇怪的行为,请发布内部异常

答案 1 :(得分:0)

因此,我们在课堂建设中发现了一些错误(见评论)。在这种情况下,您有两种变体。

首先,逐步反序列化对象。创建Service xml(从您的样本中手动或copypaste)并反序列化它,创建Warranty xml并反序列化它,创建Asset-without-Warranties-list xml并反序列化它,最后,创建带有Warranties的Asset xml并反序列化它。在简单的课程中找到这样的错误会更容易,并增加难度。

第二个变体:use xsd实用程序。你需要像
这样的命令 xsd.exe yourXml.xml / c
xsd.exe yourXml.xsd / c
(详见文档)。 您将在最后获得所有必需类的yourXml.cs文件。只需修复数组属性,它们有时会被非法处理。