如何反序列化这个Xml文件?

4

我有一个Xml文件,需要将其反序列化为一个类。问题是:考虑到Xml元素(RowInfo)的数量不是固定的,这个类的正确结构/设计是什么?

Xml文件:

<?xml version="1.0"?>
<SomeObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
  <Layers>   
 <Layer Id="0">
      <RowInfo>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</RowInfo>
      <RowInfo>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1</RowInfo>
      <RowInfo>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</RowInfo>
      <RowInfo>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</RowInfo>
      <RowInfo>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</RowInfo>
      <RowInfo>1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1</RowInfo>
      <RowInfo>1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</RowInfo>
      <RowInfo>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</RowInfo>
      <RowInfo>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</RowInfo>
      <RowInfo>1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1</RowInfo>
      <RowInfo>1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1</RowInfo>
      <RowInfo>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</RowInfo>
      <RowInfo>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</RowInfo>
      <RowInfo>1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1</RowInfo>
      <RowInfo>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</RowInfo>
      <RowInfo>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</RowInfo>
      <RowInfo>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</RowInfo>
      <RowInfo>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</RowInfo>
      <RowInfo>1,1,1,0,0,1,1,1,1,1,1,1,1,1,0,0,1,0,0,1</RowInfo>
      <RowInfo>1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1</RowInfo>
    </Layer>
  </Layers>   
</SomeObject>

感谢您的帮助。 谢谢。 编辑1: 还要考虑(Layers)可能包含多个层。

我想将(Layer)元素作为数组获取,但是不知道如何构建类结构:( - Robin-Hood
你可以将Layer元素作为一个私有列表,然后通过公共属性将列表转换为数组,使用ToArray()方法。 - Phil
6个回答

3
以下是一个例子 - 名称需要更改以保护隐私: 注释后的类结构
public class SomeObject 
{
  public List<Layer> Layers {get;set;}
}

public class Layer
{
  public int Id {get;set;}
  public List<RowInfo> RowInfos {get;set;}
}

public class RowInfo
{
  public List<Row> Rows {get;set;}
}

public class Row
{
  public int RowData {get;set;}
}

谢谢,但是(ID)属性属于(Layer)元素。这样可以吗? - Robin-Hood
等等,我会进行修改——不认为这很难解决。 - amelvin

2
这应该可以按照您的要求工作:
public class SomeObject
{
    public List<Layer> Layers { get; set; }
}

public class Layer
{
    [XmlAttribute]
    public int Id { get; set; }

    [XmlElement("RowInfo")]
    public List<RowInfo> RowInfos { get; set; }
}

public class RowInfo
{
    [XmlText]
    public string Info { get; set; } // you'll need to parse the list of ints manually
}

唯一的区别在于编码,但您应该能够解决它。

谢谢,简单干净,而且运行良好。我可以接受这个答案。感谢每个在这里尝试帮助我的人 :) - Robin-Hood

1
我建议使用 LINQ-to-Xml。在您的对象上有一个可以接受 XElement 参数的构造函数,然后进行类似以下的操作:
public class YourObject()
{
public IEnumerable<Layer> Layers { get; set; }
public int Id { get; set; }

     public YourObj(XElement x)
     {
        this.Id = int.Parse(x.Attribute("Id").ToString());
        this.Layers = from layer in x.Elements("Layer") 
                  select new Layer(layer);
     }
}



var objs = (from c in XElement.Load("your.xml").Elements("layer") 
          select new YourObject(c)).ToList() ;

1
XmlSerializer serializer = new XmlSerializer(typeof(SomeObject));

你可以使用以下代码中的 XmlSerializer 并调用 Deserialize :)
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.4952
//
//     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=2.0.50727.3038.
// 


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[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 SomeObject {

    private SomeObjectLayers layersField;

    /// <remarks/>
    public SomeObjectLayers Layers {
        get {
            return this.layersField;
        }
        set {
            this.layersField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class SomeObjectLayers {

    private SomeObjectLayersLayer layerField;

    /// <remarks/>
    public SomeObjectLayersLayer Layer {
        get {
            return this.layerField;
        }
        set {
            this.layerField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class SomeObjectLayersLayer {

    private decimal[] rowInfoField;

    private int idField;

    private bool idFieldSpecified;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("RowInfo")]
    public decimal[] RowInfo {
        get {
            return this.rowInfoField;
        }
        set {
            this.rowInfoField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public int Id {
        get {
            return this.idField;
        }
        set {
            this.idField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool IdSpecified {
        get {
            return this.idFieldSpecified;
        }
        set {
            this.idFieldSpecified = value;
        }
    }
}

谢谢,我需要尝试一下。我看到这是自动生成的代码,使用的是什么工具? - Robin-Hood
我基于XML创建了一个通用架构,并使用xsd.exe /classes生成了类。 - Bala R

1
如果 RowInfo 的计数不是恒定的,请在您的类中使用一个 List

0

检查一个叫做 XSD.exe 的工具,它随 Visual Studio 一起提供,并允许您从 XML 文件生成代码。

您应该在程序文件菜单中看到它,就在 Visual Studio 旁边。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接