使用Linq将XML数据解析成c#中的对象

Using Linq to parse XML data into an object in c#

我有一个相当混乱的 XML 结构,我需要处理并显示给最终用户。 XML 结构包含有关金属条和要为每个条进行切割的信息。目标是处理此文件,向用户显示按条类型分组的条列表。他们可以 select 此列表中的一个栏,其中某种网格视图将显示该栏的剪切。然后他们可以 select 进行切割,该切割的标签信息将用于创建带有条形码和其他一些信息的标签。

XML的结构如下所示:

 <BODY>
<BAR>
  <BRAN>ALSPEC</BRAN>
  <SYST>Hunter 100mm Flush Glazed</SYST>
  <CODE>AS308</CODE>
  <DESC>Door Adaptor</DESC>
  <DICL>NOTRE DAME GLOSS</DICL>
  <DOCL>notre dame gloss p/coat</DOCL>
  <LEN> 6500</LEN>
  <STS>1</STS>
  <POS> 0</POS>
  <SVL> 0</SVL>
  <IVL> 0</IVL>
  <VROT> 0</VROT>
  <VU1S> 0</VU1S>
  <VU1D> 0</VU1D>
  <VU2S> 0</VU2S>
  <VU2D> 0</VU2D>
  <LENR> 201.3</LENR>
  <H> 26.5</H>
  <MLT> 1</MLT>
  <SCP> 0</SCP>
  <BRS> 0</BRS>
  <IFS> 0</IFS>
  <BS1L> 0</BS1L>
  <BS1R> 0</BS1R>
  <BS2L> 0</BS2L>
  <BS2R> 0</BS2R>
  <ENTH> 0</ENTH>
  <CUT>
    <NUM> 1</NUM>
    <TYPE></TYPE>
    <ANGL> 45</ANGL>
    <ANGR> 90</ANGR>
    <AB1> 90</AB1>
    <AB2> 90</AB2>
    <IL> 2064</IL>
    <OL> 2090.5</OL>
    <BCOD>000000231/5/44</BCOD>
    <CSNA></CSNA>
    <CSNU></CSNU>
    <TINA></TINA>
    <DESC>Jamb - Right</DESC>
    <STAT> 1</STAT>
    <LBL>Job# 760  Item# 5</LBL>
    <LBL>2090.5 mm</LBL>
    <LBL>W2-D8/T15</LBL>
    <LBL>Jamb - Right</LBL>
  </CUT>
  <CUT>
    <NUM> 1</NUM>
    <TYPE></TYPE>
    <ANGL> 45</ANGL>
    <ANGR> 90</ANGR>
    <AB1> 90</AB1>
    <AB2> 90</AB2>
    <IL> 2064</IL>
    <OL> 2090.5</OL>
    <BCOD>000000231/2/45</BCOD>
    <CSNA></CSNA>
    <CSNU></CSNU>
    <TINA></TINA>
    <DESC>Jamb - Right</DESC>
    <STAT> 1</STAT>
    <LBL>Job# 760  Item# 2</LBL>
    <LBL>2090.5 mm</LBL>
    <LBL>D8/T23</LBL>
    <LBL>Jamb - Right</LBL>
  </CUT>
  <CUT>
    <NUM> 1</NUM>
    <TYPE></TYPE>
    <ANGL> 90</ANGL>
    <ANGR> 45</ANGR>
    <AB1> 90</AB1>
    <AB2> 90</AB2>
    <IL> 2064</IL>
    <OL> 2090.5</OL>
    <BCOD>000000231/1/43</BCOD>
    <CSNA></CSNA>
    <CSNU></CSNU>
    <TINA></TINA>
    <DESC>Jamb - Left</DESC>
    <STAT> 1</STAT>
    <LBL>Job# 760  Item# 1</LBL>
    <LBL>2090.5 mm</LBL>
    <LBL>D8/T24</LBL>
    <LBL>Jamb - Left</LBL>
  </CUT>
</BAR>
 </BODY>

我正在寻找的结果如下所示,即左侧的树视图和右侧的数据网格视图显示作业中的所有裁剪,由树视图过滤 selection(仅裁剪从 selected 树视图级别向下)。

GUI Layout

为了实现这一点,我正在尝试使用 LINQ to XML 将 XML 文件解析为我创建的 class:

public List<Bars> bars = new List<Bars>();

    public class Bars
    {
        public int Bar_id { set; get; }
        public string Brand { set; get; }
        public string System { set; get; }
        public string Code { set; get; }
        public string Description { set; get; }
        public string Length { set; get; }
        public string Status { set; get; }
        public string NumBars { set; get; }
        public List<Cuts> Cuts { set;  get; }
    }

    public class Cuts
    {
        public int Cut_id { set; get; }
        public int Bar_id { set; get; }
        public string AngleL { set; get; }
        public string AngleR { set; get; }
        public string LenInn { set; get; }
        public string LenOut { set; get; }
        public string Barcode { set; get; }
        public string Description { set; get; }
        public string Status { set; get; }
        public string Label1 { set; get; }
        public string Label2 { set; get; }
        public string Label3 { set; get; }
        public string Label4 { set; get; }
    }

我实际上是在寻找有关天气的建议,这是处理此类项目的正确方法 (LINQ to XML)。我应该使用数据集还是其他形式或数据存储。

我是 XML 的新手,也是关系数据库类型的新手,因此非常感谢任何建议。提前致谢!

既然你想要一些建议,这里是一个简单的方法。对于这种情况,序列化是最简单的选择。 VS 具有为这种 xml 结构代码生成 类 的内置功能。 为此,您可以使用 Edit > Paste Special 功能。所以你的 类 看起来像;

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class BODY
{

    private BODYBAR bARField;

    /// <remarks/>
    public BODYBAR BAR
    {
        get
        {
            return this.bARField;
        }
        set
        {
            this.bARField = value;
        }
    }
}

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class BODYBAR
{

    private string bRANField;

    private string sYSTField;

    private string cODEField;

    private string dESCField;

    private string dICLField;

    private string dOCLField;

    private ushort lENField;

    private byte sTSField;

    private byte pOSField;

    private byte sVLField;

    private byte iVLField;

    private byte vROTField;

    private byte vU1SField;

    private byte vU1DField;

    private byte vU2SField;

    private byte vU2DField;

    private decimal lENRField;

    private decimal hField;

    private byte mLTField;

    private byte sCPField;

    private byte bRSField;

    private byte iFSField;

    private byte bS1LField;

    private byte bS1RField;

    private byte bS2LField;

    private byte bS2RField;

    private byte eNTHField;

    private BODYBARCUT[] cUTField;

    /// <remarks/>
    public string BRAN
    {
        get
        {
            return this.bRANField;
        }
        set
        {
            this.bRANField = value;
        }
    }

    /// <remarks/>
    public string SYST
    {
        get
        {
            return this.sYSTField;
        }
        set
        {
            this.sYSTField = value;
        }
    }

    /// <remarks/>
    public string CODE
    {
        get
        {
            return this.cODEField;
        }
        set
        {
            this.cODEField = value;
        }
    }

    /// <remarks/>
    public string DESC
    {
        get
        {
            return this.dESCField;
        }
        set
        {
            this.dESCField = value;
        }
    }

    /// <remarks/>
    public string DICL
    {
        get
        {
            return this.dICLField;
        }
        set
        {
            this.dICLField = value;
        }
    }

    /// <remarks/>
    public string DOCL
    {
        get
        {
            return this.dOCLField;
        }
        set
        {
            this.dOCLField = value;
        }
    }

    /// <remarks/>
    public ushort LEN
    {
        get
        {
            return this.lENField;
        }
        set
        {
            this.lENField = value;
        }
    }

    /// <remarks/>
    public byte STS
    {
        get
        {
            return this.sTSField;
        }
        set
        {
            this.sTSField = value;
        }
    }

    /// <remarks/>
    public byte POS
    {
        get
        {
            return this.pOSField;
        }
        set
        {
            this.pOSField = value;
        }
    }

    /// <remarks/>
    public byte SVL
    {
        get
        {
            return this.sVLField;
        }
        set
        {
            this.sVLField = value;
        }
    }

    /// <remarks/>
    public byte IVL
    {
        get
        {
            return this.iVLField;
        }
        set
        {
            this.iVLField = value;
        }
    }

    /// <remarks/>
    public byte VROT
    {
        get
        {
            return this.vROTField;
        }
        set
        {
            this.vROTField = value;
        }
    }

    /// <remarks/>
    public byte VU1S
    {
        get
        {
            return this.vU1SField;
        }
        set
        {
            this.vU1SField = value;
        }
    }

    /// <remarks/>
    public byte VU1D
    {
        get
        {
            return this.vU1DField;
        }
        set
        {
            this.vU1DField = value;
        }
    }

    /// <remarks/>
    public byte VU2S
    {
        get
        {
            return this.vU2SField;
        }
        set
        {
            this.vU2SField = value;
        }
    }

    /// <remarks/>
    public byte VU2D
    {
        get
        {
            return this.vU2DField;
        }
        set
        {
            this.vU2DField = value;
        }
    }

    /// <remarks/>
    public decimal LENR
    {
        get
        {
            return this.lENRField;
        }
        set
        {
            this.lENRField = value;
        }
    }

    /// <remarks/>
    public decimal H
    {
        get
        {
            return this.hField;
        }
        set
        {
            this.hField = value;
        }
    }

    /// <remarks/>
    public byte MLT
    {
        get
        {
            return this.mLTField;
        }
        set
        {
            this.mLTField = value;
        }
    }

    /// <remarks/>
    public byte SCP
    {
        get
        {
            return this.sCPField;
        }
        set
        {
            this.sCPField = value;
        }
    }

    /// <remarks/>
    public byte BRS
    {
        get
        {
            return this.bRSField;
        }
        set
        {
            this.bRSField = value;
        }
    }

    /// <remarks/>
    public byte IFS
    {
        get
        {
            return this.iFSField;
        }
        set
        {
            this.iFSField = value;
        }
    }

    /// <remarks/>
    public byte BS1L
    {
        get
        {
            return this.bS1LField;
        }
        set
        {
            this.bS1LField = value;
        }
    }

    /// <remarks/>
    public byte BS1R
    {
        get
        {
            return this.bS1RField;
        }
        set
        {
            this.bS1RField = value;
        }
    }

    /// <remarks/>
    public byte BS2L
    {
        get
        {
            return this.bS2LField;
        }
        set
        {
            this.bS2LField = value;
        }
    }

    /// <remarks/>
    public byte BS2R
    {
        get
        {
            return this.bS2RField;
        }
        set
        {
            this.bS2RField = value;
        }
    }

    /// <remarks/>
    public byte ENTH
    {
        get
        {
            return this.eNTHField;
        }
        set
        {
            this.eNTHField = value;
        }
    }

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

/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class BODYBARCUT
{

    private byte nUMField;

    private object tYPEField;

    private byte aNGLField;

    private byte aNGRField;

    private byte aB1Field;

    private byte aB2Field;

    private ushort ilField;

    private decimal olField;

    private string bCODField;

    private object cSNAField;

    private object cSNUField;

    private object tINAField;

    private string dESCField;

    private byte sTATField;

    private string[] lBLField;

    /// <remarks/>
    public byte NUM
    {
        get
        {
            return this.nUMField;
        }
        set
        {
            this.nUMField = value;
        }
    }

    /// <remarks/>
    public object TYPE
    {
        get
        {
            return this.tYPEField;
        }
        set
        {
            this.tYPEField = value;
        }
    }

    /// <remarks/>
    public byte ANGL
    {
        get
        {
            return this.aNGLField;
        }
        set
        {
            this.aNGLField = value;
        }
    }

    /// <remarks/>
    public byte ANGR
    {
        get
        {
            return this.aNGRField;
        }
        set
        {
            this.aNGRField = value;
        }
    }

    /// <remarks/>
    public byte AB1
    {
        get
        {
            return this.aB1Field;
        }
        set
        {
            this.aB1Field = value;
        }
    }

    /// <remarks/>
    public byte AB2
    {
        get
        {
            return this.aB2Field;
        }
        set
        {
            this.aB2Field = value;
        }
    }

    /// <remarks/>
    public ushort IL
    {
        get
        {
            return this.ilField;
        }
        set
        {
            this.ilField = value;
        }
    }

    /// <remarks/>
    public decimal OL
    {
        get
        {
            return this.olField;
        }
        set
        {
            this.olField = value;
        }
    }

    /// <remarks/>
    public string BCOD
    {
        get
        {
            return this.bCODField;
        }
        set
        {
            this.bCODField = value;
        }
    }

    /// <remarks/>
    public object CSNA
    {
        get
        {
            return this.cSNAField;
        }
        set
        {
            this.cSNAField = value;
        }
    }

    /// <remarks/>
    public object CSNU
    {
        get
        {
            return this.cSNUField;
        }
        set
        {
            this.cSNUField = value;
        }
    }

    /// <remarks/>
    public object TINA
    {
        get
        {
            return this.tINAField;
        }
        set
        {
            this.tINAField = value;
        }
    }

    /// <remarks/>
    public string DESC
    {
        get
        {
            return this.dESCField;
        }
        set
        {
            this.dESCField = value;
        }
    }

    /// <remarks/>
    public byte STAT
    {
        get
        {
            return this.sTATField;
        }
        set
        {
            this.sTATField = value;
        }
    }

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

然后你可以简单地反序列化;

    BODY objBody = new BODY();
    var xml = File.ReadAllText(@"C:\XMLFile2.xml");
    using (var reader = new StringReader(xml))
    {
        var serialiser = new XmlSerializer(typeof(BODY));
        objBody = (BODY)serialiser.Deserialize(reader);
    }

如果可以选择,我会彻底推荐使用 XDocument(LINQ to XML)。创建文档和处理它们要简单得多。就个人而言,我更喜欢处理大 Xml.

var result = doc.Descendants("BAR")
    .Select((e, i)=> new Bars()
            {
                Bar_id = i +1, 
                Brand  = e.Element("BRAN").Value,
                System = e.Element("SYST").Value,
                Code = e.Element("CODE").Value,
                Description = e.Element("DESC").Value,
                Length =e.Element("LEN").Value,
                Status =e.Element("STS").Value,     
                // remaining fileds
                Cuts  = e.Descendants("CUT").Select(c=> new Cuts() 
                                                 {
                                                     Cut_id =  int.Parse(c.Element("NUM").Value),
                                                     Bar_id = i+1,
                                                     AngleL = c.Element("ANGL").Value,
                                                     AngleR = c.Element("ANGR").Value,
                                                     LenInn = c.Element("IL").Value,
                                                     LenOut = c.Element("OL").Value,                                                             
                                                     Barcode = c.Element("BCOD").Value,
                                                     Description = c.Element("DESC").Value,
                                                     Status = c.Element("STAT").Value,
                                                     Label1 = c.Elements("LBL").First().Value,
                                                     Label2 = c.Elements("LBL").Skip(1).First().Value,
                                                     Label3 = c.Elements("LBL").Skip(2).First().Value,
                                                     Label4 = c.Elements("LBL").Skip(3).First().Value,

                                                 }).ToList(),
            }).ToList();        

工作Demo