获取独特元素的位置在一个字符串[](Get the positions of unique elem

2019-11-03 16:27发布

我有我访问创建的花费在项目时间报告的XML文件。 我回国的独特日期上的winform动态创建一个标签,并希望编译花在一个项目,每一个独特的日期和具体时间。 我已经能够返回所有项目的每个日期或只有一个项目下。 目前我卡上只有一个返回项目。 谁能帮帮我吗?? 这是该数据应该是什么样子,如果它是正确的。

04/11/15
    26820   2.25
    27111   8.00
04/12/15
    26820   8.00
04/13/15
    01det   4.33
    26820   1.33
    27225   4.25

etc.

这是我如何检索数据

         string[] weekDateString = elementDateWeekstring();
         string[] uniqueDates = null;
         string[] weeklyJobNumber = elementJobNumWeek();
         string[] weeklyTicks = elementTicksWeek();

这是我应得的唯一日期。

         IEnumerable<string> distinctWeekDateIE = weekDateString.Distinct();

         foreach (string d in distinctWeekDateIE)
         {
             uniqueDates = distinctWeekDateIE.ToArray();
         }

这是我如何创建标签。

        try
         {
              int dateCount;
              dateCount = uniqueDates.Length;

              Label[] lblDate = new Label[dateCount];
              int htDate = 1;
              int padDate = 10;

              for (int i = 0; i < dateCount; i++ )
              {
                   lblDate[i] = new Label();

                   lblDate[i].Name = uniqueDates[i].Trim('\r');

                   lblDate[i].Text = uniqueDates[i];

                   lblDate[i].TabIndex = i;

                   lblDate[i].Bounds = new Rectangle(18, 275 + padDate + htDate, 75, 22);

                   targetForm.Controls.Add(lblDate[i]);

                   htDate += 22;

                   foreach (string x in uniqueDates)
                   {
                        int[] posJobNumber;

                       posJobNumber = weekDateString.Select((b, a) => b == uniqueDates[i].ToString() ? a : -1).Where(a => a != -1).ToArray();

                        for (int pjn = 0; pjn < posJobNumber.Length; pjn++)
                        {

                             if (x.Equals(lblDate[i].Text))
                             {

                                  Label lblJobNum = new Label();

                                  int htJobNum = 1;
                                  int padJobNum = 10;

                                  lblJobNum.Name = weeklyJobNumber[i];

                                  lblJobNum.Text = weeklyJobNumber[i];

                                  lblJobNum.Bounds = new Rectangle(100, 295 + padJobNum + htJobNum, 75, 22);

                                  targetForm.Controls.Add(lblJobNum);

                                  htJobNum += 22;
                                  htDate += 22;
                                  padJobNum += 22;
                             }
                        }

                     }
              }
         }

我一直停留在这3个月左右。 是否有任何人可以给我描述为什么我不能够正确地检索与特定日期相关的工作数量。 我不相信这些是专门被返回日期。 只是一个字符串,它看起来像一个日期。

我非常感谢所有帮助我能。 我只是完全莫名其妙。 感谢您预先任何响应。 我真正体会到了帮助。

编辑:@Sayka - 这里是XML样本。

<?xml version="1.0" encoding="utf-8"?>
<Form1>
  <Name Key="4/21/2014 6:51:17 AM">
    <Date>4/21/2014</Date>
    <JobNum>26820</JobNum>
    <RevNum>00000</RevNum>
    <Task>Modeling Secondary</Task>
    <Start>06:51 AM</Start>
    <End>04:27 PM</End>
    <TotalTime>345945089017</TotalTime>
  </Name>
  <Name Key="4/22/2014 5:44:22 AM">
    <Date>4/22/2014</Date>
    <JobNum>26820</JobNum>
    <RevNum>00000</RevNum>
    <Task>Modeling Secondary</Task>
    <Start>05:44 AM</Start>
    <End>06:56 AM</End>
    <TotalTime>43514201221</TotalTime>
  </Name>
  <Name Key="4/22/2014 6:57:02 AM">
    <Date>4/22/2014</Date>
    <JobNum>02e-n-g</JobNum>
    <RevNum>00000</RevNum>
    <Task>NET Eng</Task>
    <Start>06:57 AM</Start>
    <End>07:16 AM</End>
    <TotalTime>11706118875</TotalTime>
  </Name>
....
</Form1>

这是我应得的信息出来的XML文件,并返回一个字符串[]。

    public static string[] elementDateWeekstring()
    {
        //string datetxtWeek = "";
        XmlDocument xmldoc = new XmlDocument();

        fileExistsWeek(xmldoc);

        XmlNodeList nodeDate = xmldoc.GetElementsByTagName("Date");

        int countTicks = 0;
        string[] dateTxtWeek = new string[nodeDate.Count];


        for (int i = 0; i < nodeDate.Count; i++)
        {
            dateTxtWeek[i] = nodeDate[i].InnerText;
            countTicks++;

        }
        return dateTxtWeek;
    }

工作数量和蜱以类似的方式返回。 我已经能够重新使用这些片段throught出来的代码。 这是一个维的xml文件? 它总是返回这相当于一个日期或蜱一个jobnumber可以的位置。 我将永远不会有任何一个要素更多或更少。

Answer 1:

你可以使用LINQ到XML解析XML文件,然后按作业的日期和顺序按职位名称中使用LINQ到对象组(并序)数据每个组。

解析XML文件的代码如下所示:

var doc = XDocument.Load(filename);
var jobs = doc.Descendants("Name");

// Extract the date, job number, and total time from each "Name" element.:

var data = jobs.Select(job => new
{
    Date = (DateTime)job.Element("Date"),
    Number = (string)job.Element("JobNum"),
    Duration = TimeSpan.FromTicks((long)job.Element("TotalTime"))
});

以组代码和按日期的作业,命令组由作业名称是:

var result = 
    data.GroupBy(job => job.Date).OrderBy(g => g.Key)
    .Select(g => new
    {
        Date = g.Key, 
        Jobs = g.OrderBy(item => item.Number)
    });

然后,你可以通过遍历每个组中访问数据result ,然后遍历每个作业组中,像这样:

foreach (var jobsOnDate in result)
{
    Console.WriteLine("{0:d}", jobsOnDate.Date);

    foreach (var job in jobsOnDate.Jobs)
        Console.WriteLine("    {0}  {1:hh\\:mm}", job.Number, job.Duration);
}

在样品编译控制台应用程序(代替XML文件作为适当的文件名)把此一起:

using System;
using System.Linq;
using System.Xml.Linq;

namespace ConsoleApplication2
{
    class Program
    {
        private static void Main()
        {
            string filename = @"d:\test\test.xml"; // Substitute your own filename here.

            // Open XML file and get a collection of each "Name" element.            

            var doc = XDocument.Load(filename);
            var jobs = doc.Descendants("Name");

            // Extract the date, job number, and total time from each "Name" element.:

            var data = jobs.Select(job => new
            {
                Date = (DateTime)job.Element("Date"),
                Number = (string)job.Element("JobNum"),
                Duration = TimeSpan.FromTicks((long)job.Element("TotalTime"))
            });

            // Group the jobs by date, and order the groups by job name:

            var result = 
                data.GroupBy(job => job.Date).OrderBy(g => g.Key)
                .Select(g => new
                {
                    Date = g.Key, 
                    Jobs = g.OrderBy(item => item.Number)
                });

            // Print out the results:

            foreach (var jobsOnDate in result)
            {
                Console.WriteLine("{0:d}", jobsOnDate.Date);

                foreach (var job in jobsOnDate.Jobs)
                    Console.WriteLine("    {0}  {1:hh\\:mm}", job.Number, job.Duration);
            }
        }
    }
}


Answer 2:

输出是这样的

创建一个新项目

设置窗体大小大。

应用这些代码。

设置你的XML文件的位置。

命名空间

using System.Xml;
using System.IO;

表单代码

public partial class Form1 : Form
{
    const string XML_FILE_NAME = "D:\\emps.txt";
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        prepareDataGrid();
        List<JOBS> jobsList = prepareXML(XML_FILE_NAME);
        for (int i = 0; i < jobsList.Count; i++)
        {
            addDateRow(jobsList[i].jobDate.ToString("M'/'d'/'yyyy"));
            for (int j = 0; j < jobsList[i].jobDetailsList.Count; j++)
                dgv.Rows.Add(new string[] { 
                    jobsList[i].jobDetailsList[j].JobNumber,
                    jobsList[i].jobDetailsList[j].JobHours
                });
        }
    }

    DataGridView dgv;
    void prepareDataGrid()
    {
        dgv = new DataGridView();
        dgv.BackgroundColor = Color.White;
        dgv.GridColor = Color.White;
        dgv.DefaultCellStyle.SelectionBackColor = Color.White;
        dgv.DefaultCellStyle.SelectionForeColor = Color.Black;
        dgv.DefaultCellStyle.ForeColor = Color.Black;
        dgv.DefaultCellStyle.BackColor = Color.White;
        dgv.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
        dgv.Width = 600;
        dgv.Dock = DockStyle.Left;
        this.BackColor = Color.White;
        dgv.Columns.Add("Col1", "Col1");
        dgv.Columns.Add("Col2", "Col2");
        dgv.Columns[0].Width = 110;
        dgv.Columns[1].Width = 40;
        dgv.DefaultCellStyle.Font = new System.Drawing.Font("Segoe UI", 10);
        dgv.RowHeadersVisible = dgv.ColumnHeadersVisible = false;
        dgv.AllowUserToAddRows =
        dgv.AllowUserToDeleteRows =
        dgv.AllowUserToOrderColumns =
        dgv.AllowUserToResizeColumns =
        dgv.AllowUserToResizeRows =
        !(dgv.ReadOnly = true);
        Controls.Add(dgv);
    }

    void addJobRow(string jobNum, string jobHours)
    {
        dgv.Rows.Add(new string[] {jobNum, jobHours });
    }

    void addDateRow(string date)
    {
        dgv.Rows.Add(new string[] { date, ""});
        dgv.Rows[dgv.Rows.Count - 1].DefaultCellStyle.SelectionForeColor =
        dgv.Rows[dgv.Rows.Count - 1].DefaultCellStyle.ForeColor = Color.Firebrick;
        dgv.Rows[dgv.Rows.Count - 1].DefaultCellStyle.Font = new Font("Segoe UI Light", 13.5F);
        dgv.Rows[dgv.Rows.Count - 1].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
        dgv.Rows[dgv.Rows.Count - 1].Height = 25;
    }

    List<JOBS> prepareXML(string fileName)
    {
        string xmlContent = "";
        using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
        using (StreamReader sr = new StreamReader(fs)) xmlContent = sr.ReadToEnd();
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xmlContent);

        List<JOBS> jobsList = new List<JOBS>();
        XmlNode form1Node = doc.ChildNodes[1];
        for (int i = 0; i < form1Node.ChildNodes.Count; i++)
        {
            XmlNode dateNode = form1Node.ChildNodes[i].ChildNodes[0].ChildNodes[0],
                jobNumNode = form1Node.ChildNodes[i].ChildNodes[1].ChildNodes[0],
                timeTicksNode = form1Node.ChildNodes[i].ChildNodes[6].ChildNodes[0];

            bool foundDate = false;
            for (int j = 0; j < jobsList.Count; j++) if (jobsList[j].compareDate(dateNode.Value))
                {
                    jobsList[j].addJob(jobNumNode.Value, Math.Round(TimeSpan.FromTicks(
                        (long)Convert.ToDouble(timeTicksNode.Value)).TotalHours, 2).ToString());
                    foundDate = true;
                    break;
                }
            if (!foundDate)
            {
                JOBS job = new JOBS(dateNode.Value);
                string jbnum = jobNumNode.Value;
                string tbtck = timeTicksNode.Value;
                long tktk = Convert.ToInt64(tbtck);
                double tkdb = TimeSpan.FromTicks(tktk).TotalHours;
                job.addJob(jobNumNode.Value, Math.Round(TimeSpan.FromTicks(
                        Convert.ToInt64(timeTicksNode.Value)).TotalHours, 2).ToString());
                jobsList.Add(job);
            }
        }
        jobsList.OrderByDescending(x => x.jobDate);
        return jobsList;
    }

    class JOBS
    {
        public DateTime jobDate;
        public List<JobDetails> jobDetailsList = new List<JobDetails>();

        public void addJob(string jobNumber, string jobHours)
        {
            jobDetailsList.Add(new JobDetails() { JobHours = jobHours, JobNumber = jobNumber });
        }
        public JOBS(string dateString)
        {
            jobDate = getDateFromString(dateString);
        }

        public JOBS() { }

        public bool compareDate(string dateString)
        {
            return getDateFromString(dateString) == jobDate;
        }

        private DateTime getDateFromString(string dateString)
        {
            string[] vals = dateString.Split('/');
            return new DateTime(Convert.ToInt32(vals[2]), Convert.ToInt32(vals[0]), Convert.ToInt32(vals[1]));
        }
    }

    class JobDetails
    {
        public string JobNumber { get; set; }
        public string JobHours { get; set; }
    }
}


文章来源: Get the positions of unique elements in a string[]