繁体   English   中英

C#LINQ to XML-如何基于子元素过滤节点?

[英]C# LINQ to XML - How can I filter nodes based on a child element?

给定以下XML(为简洁起见,它是局部的),我尝试仅在名称为C006的CELL元素的VALUE元素不是给定值的情况下创建一个新对象。

<alv:AREAS>
    <alv:TABLE>
        <alv:COLUMNS>
        <alv:ROWS>
            <ROWNUMBER>9 </ROWNUMBER>
                <ROW type="D" index="0 ">
                <ROW type="D" index="8 ">
                    <CELL name="C001" visible="X" imagefirst="" imageid="0001"/>
                    <CELL name="C002" visible="X">
                        <VALUE>A7F30024579</VALUE>
                    </CELL>
                    <CELL name="C003" visible="X">
                        <VALUE>Xfrmr 40VA,120-24V,single hub,Class II U</VALUE>
                    </CELL>
                    <CELL name="C004" visible="X">
                        <VALUE decimals="0">3</VALUE>
                    </CELL>
                    <CELL name="C005" visible="X">
                        <VALUE>PTO</VALUE>
                    </CELL>
                    <CELL name="C006" visible="X">
                        <VALUE>BANC</VALUE>
                    </CELL>
                </ROW>
        </ROWS>
    </COLUMNS>
</TABLE>

我认为以下内容可能会为我提供所需的信息,但我认为我试图将过滤器的等级过高(针对CELL的选择)。 没有筛选器,我的列表创建按预期的方式。 放置好过滤器后,没有元素可供进一步选择。

var rows = xml.Descendants(ns + "ROWS")
            .SelectMany(row => row.Elements("ROW")).Where(r => r.Attribute("type").Value == "D")
            .Select(c => c.Elements("CELL")).Where(f => f.Attribute("name").Value == "C006").Select(v => v.Element("VALUE").Value != "LEIS"))
            .Select(d => new SAPDevice
            {
                MaterialNumber = d.Where(cell => cell.Attribute("name").Value == "C002").Select(val => val.Element("VALUE").Value).First(),
                PartNumber = d.Where(cell => cell.Attribute("name").Value == "C011").Select(val => val.Element("VALUE").Value).First(),
                Quantity = System.Convert.ToInt32(d.Where(cell => cell.Attribute("name").Value == "C004").Select(val => val.Element("VALUE").Value).First()),
                Price = System.Convert.ToDecimal(d.Where(cell => cell.Attribute("name").Value == "C008").Select(val => val.Element("VALUE").Value).First()),
                Description = d.Where(cell => cell.Attribute("name").Value == "C003").Select(val => val.Element("VALUE").Value).First()//,
                //MaterialType = d.Where(cell => cell.Attribute("name").Value == "C006").Select(val => val.Element("VALUE").Value).First()
            }).ToList();

我认为'.Where'需要应用于d,但我不确定如何。 谢谢参观。

编辑7/19:以下查询返回所有行,无论过滤器值如何:

var rows = xml.Descendants(ns + "ROWS")
            .SelectMany(row => row.Elements("ROW")).Where(r => r.Attribute("type").Value == "D")
            .Select(c => c.Elements("CELL")).Where(f => !f.Elements("CELL").Any(f1 => ((string)f1.Attribute("name") == "C006") && ((string)f1.Element("VALUE") == "BANC")))
            .Select(d => new SAPDevice
            {
                MaterialNumber = d.Where(cell => cell.Attribute("name").Value == "C002").Select(val => val.Element("VALUE").Value).First(),
                PartNumber = d.Where(cell => cell.Attribute("name").Value == "C011").Select(val => val.Element("VALUE").Value).First(),
                Quantity = System.Convert.ToInt32(d.Where(cell => cell.Attribute("name").Value == "C004").Select(val => val.Element("VALUE").Value).First()),
                Price = System.Convert.ToDecimal(d.Where(cell => cell.Attribute("name").Value == "C008").Select(val => val.Element("VALUE").Value).First()),
                Description = d.Where(cell => cell.Attribute("name").Value == "C003").Select(val => val.Element("VALUE").Value).First()//,
                //MaterialType = d.Where(cell => cell.Attribute("name").Value == "C006").Select(val => val.Element("VALUE").Value).First()
            }).ToList();

尝试以下操作:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication120
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument xml = XDocument.Load(FILENAME);
            XElement root = xml.Root;
            XNamespace ns = root.GetNamespaceOfPrefix("alv");

            var results = xml.Descendants(ns + "ROWS").SelectMany(rows =>
               rows.Descendants("ROW").Where(r => r.Attribute("type").Value == "D")
               .Where(f => !f.Elements("CELL").Any(f1 => ((string)f1.Attribute("name") == "C006") && ((string)f1.Element("VALUE") == "LEIS")))
               .Select(d => new SAPDevice()
               {
                   MaterialNumber = (string)d.Elements("CELL").Where(cell => (string)cell.Attribute("name") == "C002").Select(val => val.Element("VALUE")).FirstOrDefault(),
                   PartNumber = d.Elements("CELL").Where(cell => (string)cell.Attribute("name") == "C011").Select(val => (string)val.Element("VALUE")).FirstOrDefault(),
                   Quantity = (int?)d.Elements("CELL").Where(cell => (string)cell.Attribute("name") == "C004").Select(val => val.Element("VALUE")).FirstOrDefault(),
                   Price = (decimal?)d.Elements("CELL").Where(cell => (string)cell.Attribute("name") == "C008").Select(val => val.Element("VALUE")).FirstOrDefault(),
                   Description = (string)d.Elements("CELL").Where(cell => (string)cell.Attribute("name") == "C003").Select(val => val.Element("VALUE")).FirstOrDefault(),
               //     //MaterialType = d.Elements("CELL").Where(cell => cell.Attribute("name").Value == "C006").Select(val => val.Element("VALUE").Value).First()
               })).ToList();
        }

    }
    public class SAPDevice
    {
        public object test { get; set; }
        public string MaterialNumber { get; set; }
        public string PartNumber { get; set; }
        public int? Quantity { get; set; }
        public decimal? Price { get; set; }
        public string Description { get; set; }
    }


}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM