【问题标题】:Reading a Childs child attribute with Linq使用 Linq 读取 Childs 子属性
【发布时间】:2021-08-16 02:04:42
【问题描述】:

我有一个 xml 文档

<CollRpt>
   <Sumry SumryID="0001">
      <BT BTID="1234" >
         <FT FTID="24240981145200123809844" >
          </FT>
         <AcctCls CrInd="1">
            <Ckey/>
         </AcctCls>
      </BT>
      <Vchr  VchrID="215"/>
      <Tot TotCnt="4"/>
   </Sumry>
</CollRpt>

只有当 Vchr 元素的 VchrID == 215 时,我才需要从每个“Sumry”元素和子元素中获取多个属性。我已经尝试了几种不同的方法,但都没有运气。任何指导将不胜感激。

 var xml = XDocument.Load(@newFile);
            var query = (from c in xml.Root.Descendants("CollRpt")
                         let s = c.Descendants("Sumry")
                         let v = s.Elements("Vchr")
                         where v.Attributes("VchrFormCd").Equals("215")
                         select new { SumryID = s.Attributes("SumryID"), ALC = v.Attributes("VchrID") }).ToList();

           
            foreach (var q in query)
            {
                Console.WriteLine("{0}: {1}\n", q.SumryID ,q.VchrID);
            }

【问题讨论】:

  • 我认为有多个摘要正确吗?
  • 是的,你是对的。

标签: c# xml linq


【解决方案1】:

只有当 Vchr 元素的 VchrID == 215 时,我才需要从每个“Sumry”元素和子元素中获取多个属性。我已经尝试了几种不同的方法,但都没有运气。任何指导将不胜感激

我建议创建类,以便您可以将此 xml 反序列化为易于搜索、过滤等的类。请参阅下面的内容。

[XmlRoot(ElementName = "FT")]
    public class FT
    {

        [XmlAttribute(AttributeName = "FTID")]
        public double FTID { get; set; }
    }

    [XmlRoot(ElementName = "AcctCls")]
    public class AcctCls
    {

        [XmlElement(ElementName = "Ckey")]
        public object Ckey { get; set; }

        [XmlAttribute(AttributeName = "CrInd")]
        public int CrInd { get; set; }
    }

    [XmlRoot(ElementName = "BT")]
    public class BT
    {

        [XmlElement(ElementName = "FT")]
        public FT FT { get; set; }

        [XmlElement(ElementName = "AcctCls")]
        public AcctCls AcctCls { get; set; }

        [XmlAttribute(AttributeName = "BTID")]
        public int BTID { get; set; }
    }

    [XmlRoot(ElementName = "Vchr")]
    public class Vchr
    {

        [XmlAttribute(AttributeName = "VchrID")]
        public int VchrID { get; set; }
    }

    [XmlRoot(ElementName = "Tot")]
    public class Tot
    {

        [XmlAttribute(AttributeName = "TotCnt")]
        public int TotCnt { get; set; }
    }

    [XmlRoot(ElementName = "Sumry")]
    public class Sumry
    {

        [XmlElement(ElementName = "BT")]
        public BT BT { get; set; }

        [XmlElement(ElementName = "Vchr")]
        public Vchr Vchr { get; set; }

        [XmlElement(ElementName = "Tot")]
        public Tot Tot { get; set; }

        [XmlAttribute(AttributeName = "SumryID")]
        public int SumryID { get; set; }
    }

    [XmlRoot(ElementName = "CollRpt")]
    public class CollRpt
    {

        [XmlElement(ElementName = "Sumry")]
        public List<Sumry> Sumry { get; set; }
    }

现在您可以通过以下方式反序列化此 xml:

using (var fileStream = new FileStream("YOURXMLPATH", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            using (StreamReader reader = new StreamReader(fileStream))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(CollRpt));
                var test = (CollRpt)serializer.Deserialize(reader);

                var found = test.Sumry.Where(s => s.Vchr.VchrID == 215).ToList();
            }
        }

在上面,test 将是 CollRpt 类,其中包含您需要的所有数据。在found 中,它将包含您根据条件过滤的数据的List&lt;Sumry&gt;

【讨论】:

  • 如何获取 FT (Sumry/BT/FT) 中的信息?
  • @David Austin 每个Sumry 都有一个BT 属性,并且该属性还有另一个名为FT 的属性。因此,如果您有一个 Sumry 的列表,至少说一个项目,您可以通过访问该列表中的第一个项目来执行类似的操作:var myFTID= list[0].BT.FT.FTID;,这将在上面的示例中得到类似于 24240981145200123809844 的内容。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-16
  • 2021-03-07
相关资源
最近更新 更多