【问题标题】:Using Linq to parse XML data into an object in c#c#中使用Linq将XML数据解析成对象
【发布时间】:2016-02-11 11:40:25
【问题描述】:

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

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>

我正在寻找的结果如下所示,即左侧的树视图和右侧的 datagridview 显示作业中的所有剪切,由树视图选择过滤(仅从选定的树视图级别向下剪切)。

GUI Layout

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

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 新手,也是关系数据库类型的新手,因此我们将不胜感激任何建议。提前致谢!

【问题讨论】:

标签: c# xml linq datagridview treeview


【解决方案1】:

如果有选择,我会彻底推荐使用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

【讨论】:

  • 嗨,哈里!,感谢您的回复!我喜欢这种方法,因为它让我可以更好地控制我实际保留的内容。我正在解析的文件中有很多我不需要的信息。我将如何修改您的代码,以便系统中的每个栏最终都有一个唯一的 id (bar_id),并且每个剪辑也使用它所属的栏的 id 设置?有没有一种简单的方法可以做到这一点,或者我应该只为每个循环使用?这样做的原因是我需要创建父子关系才能创建树视图。即 Bar_id 将是其下每个剪辑的父级...再次感谢!
  • @Will 将更新答案以生成每个栏和相应剪辑的 ID。
【解决方案2】:

既然你想要一些建议,这里是一种简单的方法。遇到这种情况,序列化是最简单的选择。 VS 具有为这种 xml 结构编写代码生成类的内置功能。 为此,您可以使用Edit &gt; 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);
    }

【讨论】:

    猜你喜欢
    • 2010-11-25
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-08
    • 2019-12-28
    • 1970-01-01
    • 2016-08-23
    相关资源
    最近更新 更多