簡體   English   中英

讀取 XML 並在 C# 中創建元素的頻率計數

[英]Reading XML and creating a frequency count of elements in C#

我有一個這種格式的 XML 文件(但只是更大):

<customer>
    <name>John</name>
    <age>24</age>
    <gender>M</gender>
</customer>
<customer>
    <name>Keith</name>
    <age></age>         <!--blank value-->
    <gender>M</gender>
</customer>
<customer>
    <name>Jenny</name>
    <age>21</age>
    <gender>F</gender>
</customer>
<customer>
    <name>John</name>   
    <age>24</age>       <!--blank value-->
    <gender>M</gender>  <!--blank value-->
</customer>

我想生成一個數據表,它將采用以下格式:

元素名稱頻率

姓名填4
姓名空白 0

滿歲2
年齡空白2

性別填充 3
性別空白1

目前我分兩部分完成這個任務,首先創建一個如上所述的數據表結構並將所有頻率設置為 0 作為默認值。 然后使用XmlReader讀取 XML,並在每次 XmlReader 找到子元素時增加頻率計數。

我的問題是,我用於添加實際計數的第二個函數對於具有許多屬性的許多客戶的非常大的 Xml 文件花費的時間太長。 我怎樣才能提高這個功能的效率?

我的代碼:

static void AddCount(DataTable dt)
{
     int count;
     using (XmlReader reader = XmlReader.Create(@"C:\Usr\sample.xml"))
     {
         while (reader.Read())
            {
                if (reader.IsStartElement())
                {
                    string eleName = reader.Name;
                    DataRow[] foundElements = dt.Select("ElementName = '" + eleName + "'");  
                    if (!reader.IsEmptyElement)
                    {
                       count = int.Parse(foundElements.ElementAt(0)["Frequency"].ToString());  
                       foundElements.ElementAt(0).SetField("Frequency", count + 1);
                    }
                    else
                    {
                       count = int.Parse(foundElements.ElementAt(0)["Frequency"].ToString());  
                       foundElements.ElementAt(0).SetField("Frequency", count + 1);
                    }
                }
            }   
       }   
  }    

我還准備將 XmlReader 類更改為針對此任務的任何其他更有效的類。 歡迎任何建議。

您可以使用以下代碼:

    using (XDocument xdoc = XDocument.Load(@"C:\Users\aks\Desktop\sample.xml"))
        {
            var customers = xdoc.Descendants("customer");
            var totalNodes = customers.Count();

            var filledNames = customers.Descendants("name").Where(x => x.Value != string.Empty).Count();
            var filledAges = customers.Descendants("age").Where(x => x.Value != string.Empty).Count();
            var filledGenders = customers.Descendants("gender").Where(x => x.Value != string.Empty).Count();

            var unfilledNames = totalNodes - filledNames;
            var unfilledAges = totalNodes - filledAges;
            var unfilledGenders = totalNodes - filledGenders;
        }

事實證明,使用 Select 操作在 DataTable 中進行查詢非常昂貴,這使得我的函數非常慢。

取而代之的是,使用Dictionary<string, ValueFrequencyModel>並對其進行查詢以使用計數填充字典,完成后,將Dictionary<string, ValueFrequencyModel>轉換為 DataTable。

這為我節省了大量時間並解決了問題。

試試這個邏輯,目前我這里只取了一個屬性,即Name

        XDocument xl = XDocument.Load(@"C:\Usr\sample.xml");
        var customers = xl.Descendants("Customer");
        var customerCount = customers.Count();
        var filledCustomers = customers.Where(x => x.Element("Name").Value != string.Empty).Count();
        var nonfilledCustomers = customerCount - filledCustomers;

暫無
暫無

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

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