C # Объявление 2D-массива, не зная его размера из XML-документа - PullRequest
0 голосов
/ 04 октября 2018

Я хотел бы использовать 2D-массив, не зная его размера, потому что данные поступают из XML-документа.Итак, как мне объявить этот массив?

Вот мой код:

List<string> eventList = new List<string>();
string[,] eventArray;

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(new StringReader(xmlData));

string xmlPathPattern = "//file//ALL_INSTANCES//instance";
XmlNodeList myNodeList = xmlDoc.SelectNodes(xmlPathPattern);
foreach (XmlNode node in myNodeList)
{
    XmlNode id = node.FirstChild;
    XmlNode start = id.NextSibling;
    XmlNode end = start.NextSibling;
    XmlNode code = end.NextSibling;
}

Я хочу заполнить массив порядком [code] [id] [start] [end]

В документе XML есть много идентификаторов для одного кода, и для каждого идентификатора есть 1 начало и 1 конец.Поэтому я не знаю количество кодов, а не количество идентификаторов

Фрагмент XML-файла:

<file>
     <ALL_INSTANCES>
          <instance>
               <ID>1</ID>
               <start>213.5000000000</start>
               <end>223.5000000000</end>
               <code>Bert</code>
               <label>
                    <text>Bert Doe</text>
               </label>
          </instance>
          <instance>
               <ID>2</ID>
               <start>213.5000000000</start>
               <end>231.3900001049</end>
               <code>John</code>
               <label>
                    <text>John Doe</text>
               </label>
               <label>
                    <text>Cross</text>
               </label>
          </instance>
          <instance>
               <ID>3</ID>
               <start>214.0000000000</start>
               <end>225.0000000000</end>
               <code>Passing</code>
          </instance>
          ....
     </ALL_INSTANCES>
</file>

Спасибо за помощь!:)

PS: В конце я должен заполнить выпадающее меню (в единстве), где пользователь может выбирать между кодами, а затем я распечатываю идентификаторы, их начало и конец.Если есть лучшее решение, чем массив, я бы хотел узнать это: -)

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Собираем все это вместе с отличными советами от Джона Скита и jdweng.Этот пример выполняет большую часть тяжелой работы (вам все равно придется адаптировать ее к единице).

using System;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using System.Xml.Linq;

namespace StackOverflow06
{
    public partial class EasyXML : Form
    {
        public EasyXML()
        {
            InitializeComponent();
        }
        // Overriding this event just means that the app window 
        // is now created so it's a good time to initialize 
        // something like DataGridView
        protected override void OnHandleCreated(EventArgs e)    
        {
            // Get the file, wherever it happens to be
            string fileName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\XMLFileSnippet.xml";

            // Parse the file. Use Xml.Linq AS SUGGESTED BY: @jdweng
            XElement doc = XElement.Load(fileName);  

            // Xml.Linq finds "instance" elements only
            foreach(XElement instance in doc.Descendants("instance"))
            {
                // Call constructor for each one found
                Records.Add(new Record(instance)); //... and add it to a list
            }

            // Bind the DataGridView to show this list
            dataGridView.DataSource = Records;

            // Make the column formatting look nice
            foreach (DataGridViewColumn col in dataGridView.Columns)
            {
                if (col.Name == "Labels") col.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                else col.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
            }
            base.OnHandleCreated(e);
        }
        // A class AS SUGGESTED BY: by @Jon Skeet
        class Record
        {
            public Record(XElement instance)
            {
                ID = instance.Element("ID").Value;
                Start = float.Parse(instance.Element("start").Value);
                End = float.Parse(instance.Element("end").Value);
                Code = instance.Element("code").Value;
                var labelsTmp = from label in instance.Elements("label") select label.Element("text").Value;
                Labels = string.Join(",", labelsTmp);
            }
            public string ID { get; set; }
            public float Start { get; set; }
            public float End { get; set; }
            public string Code { get; set; }
            public string Labels { get; set; }
        }
        // Make the DataGridView bound to this list of Records
        BindingList<Record> Records = new BindingList<Record>();
    }
}

enter image description here

0 голосов
/ 04 октября 2018

Чтобы уточнить: Джон предлагает, чтобы вместо массива строк вы объявляли такой класс:

class Event
{
    public string Id { get; set; }
    public float Start { get; set; }
    public float End { get; set; }
    public string Code { get; set; }
}

, а затем объявляли список следующим образом:

var events = new List<Event>();

, а затем добавьте в него свои данные следующим образом:

foreach (XmlNode node in myNodeList)
{
    XmlNode id = node.FirstChild;
    XmlNode start = id.NextSibling;
    XmlNode end = start.NextSibling;
    XmlNode code = end.NextSibling;

    var event = new Event
    {
        Id = id,
        Start = start,
        End = end,
        Code = code
    };

    events.Add(event);
}

Таким образом, вы получите хороший список строго типизированных объектов, с которыми легко работать, и вам не придется беспокоиться о них.увеличивая его, потому что List<T> растет по мере добавления к нему материала.

Обратите внимание, что этот код не будет работать сразу после установки, компилятор сообщит об ошибке, потому что вы должны использовать свойство XmlNode.Value впервое место, а затем, поскольку он возвращает строку, преобразуйте start и end в float.Исправление оставлено как упражнение для вас.Вы должны выяснить, как конвертировать из string в float, Google поможет с этим.

После того, как вы узнали это, изучите LINQ to XML, что делает чтение XML-документов быстрым (хотя вам все равно придется выполнять некоторые преобразования типов вручную).

Кстати, я объявил эти два свойства как float, но если по какой-то причине вы действительно действительно заботитесь о точности, вы должны объявить их какdecimal.

Конечно, все благодарности Джону Скиту.

Приведенный выше код вообще не тестируется, попробуйте его и исправьте все необходимые исправления.

...