簡體   English   中英

字典 <string, List<ClassObj> &gt; LINQ To XML查詢

[英]Dictionary<string, List<ClassObj>> LINQ To XML Query

我嘗試將XML文件放入帶有通用列表的字典中。 如何使用正確的鍵將正確的查詢列表合並到字典中? 而不是.ToList() .ToDictionary.ToDictionary嗎?

<?xml version="1.0"?>
<customers>
  <cust ID="1" DeviceID="1" Name="Bob" Latitude="10" Longitude="58" Device="HW1.0"> </cust>
  <cust ID="2" DeviceID="2" Name="Jack" Latitude="28" Longitude="20" Device="HW2.2"> </cust>
</customers>

//XML attribute Name is Dict Key

public class Customers
{
    public int Longitude { get; set; }
    public int Latitude { get; set; }
    public int DeviceID { get; set; }
    public string Device { get; set; }
}

class Program
{

    private static Dictionary<string, List<Customers>> ReadXmlToDict(string filename)
    {
        // Should be Key = Xml Attribute Name Value, List of class 
        Dictionary<string, List<Customers>> dict = new Dictionary<string, List<Customers>>();

        XDocument xdoc = XDocument.Load(filename);
        var querylist = (from row in xdoc.Descendants("cust")
                         select new Customers()
                         {
                             //Name = (string)row.Attribute("Name"),  // Wrong here should be the Dic key
                             DeviceID = (int)row.Attribute("DeviceID"), // list value
                             Longitude = (int)row.Attribute("Longitude"),  // list value
                             Latitude = (int)row.Attribute("Latitude"), // list value
                             Device = (string)row.Attribute("Device")  // list value
                         }).ToList();

        return null; // null for test To.List and not Dict
    }

這就是我要實現的方式,我認為它可以滿足您的需求。 您有一個名為“ Customers的類,然后想用一個鍵存儲這些客戶的列表...我不遵循這種邏輯。

我創建了一個名為Customer的類,其中包含單個客戶的信息。 由於您要返回Dictionary<string, Customer> ,其中該字符串是xml中的唯一屬性Name ,因此沒有用例將您的字典值設為List<Customer> 也許如果您使用相同的名稱擁有多個客戶,則可以使用此名稱,但是為什么不將密鑰設置為(我認為)真正唯一的標識符DeviceID

namespace TestConsole
{
    class Customer
    {
        public int DeviceID;
        public int Longitude;
        public int Latitude;
        public string Device;
    }
    class Program
    {

        private static Dictionary<string, Customer> ReadXmlToDictionary(string filename)
        {
            var dict = new Dictionary<string, Customer>();

            var doc = XDocument.Load(@"C:\test.xml");

            dict = doc.Descendants("cust")
                .ToDictionary(
                    row => (string)row.Attribute("Name"),
                    row => new Customer {
                        Device = (string)row.Attribute("Device"),
                        DeviceID = (int)row.Attribute("DeviceID"),
                        Latitude = (int)row.Attribute("Latitude"),
                        Longitude = (int)row.Attribute("Longitude")
                });

            return dict;
        }

        static void Main(string[] args)
        {
            ReadXmlToDictionary(null);
        }
    }
}

結果圖片

編輯:認為與性能相關的答案很有趣,因此決定嘗試針對此單級xml(使用ID作為唯一標識符)進行嘗試。 結果如下:

1019 Descendants took 0.0030257 seconds.
1019 Elements took 0.0028348 seconds.
10000 Descendants took 0.0098942 seconds.
10000 Elements took 0.0101478 seconds.
100000 Descendants took 0.0873025 seconds.
100000 Elements took 0.1223577 seconds.

編輯 :創建xsd,並從中生成一個類之后,您將可以如下使用它:

var parsed = XDocument.Parse(doc.ToString());

var serializer = new XmlSerializer(typeof(Xsds.customers));

var typedPayload = serializer.Deserialize(doc.Root.CreateReader());

var xmlAsClass = (TestConsole.Xsds.customers)typedPayload;

dict = xmlAsClass.cust
    .ToDictionary(
        row => (int)row.ID,
        row => new Customer {
            Device = row.Device,
            DeviceID = row.DeviceID,
            Latitude = row.Latitude,
            Longitude = row.Longitude,
            Name = row.Name
        });

您可以使用ToDictionary()擴展方法輕松完成此操作。 但是從性能角度來看,最好使用Elements()方法而不是Descendants() ; 要進一步閱讀,請閱讀此博客文章: 為什么(或何時)不應該/應該使用DESCENDANTS()方法

您的查詢將如下所示:

var customersDictionary = 
    xDoc.Root
        .Elements("cust")
        .ToDictionary(xe => 
                        xe.Attribute("Name").Value, xe => 
                        new Customers
                        {
                            DeviceID = (int)xe.Attribute("DeviceID"), 
                            Longitude = (int)xe.Attribute("Longitude"),  
                            Latitude = (int)xe.Attribute("Latitude"),
                            Device = (string)xe.Attribute("Device")
                        });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM