簡體   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