Как прочитать значение элемента внутри узла в XML-файле с помощью C#

Доброе утро ,
У меня есть файл шаблона, написанный как XML-файл таким образом

<Simulation>
<Pedestrian Name="Mother">
    <Initial_Position In_X="3" In_Y="3" />
    <Final_Position>
        <First Fin_X="6" Fin_Y="6" Time="2" />
    </Final_Position>
</Pedestrian>

Я реализовал класс для чтения файла.

while (reader.Read() || i<Number_of_pedestrian)
{
    if (reader.Name == "Pedestrian")
    {
        if (reader.HasAttributes == true)
        {
            name = reader.GetAttribute("Name");
            //MessageBox.Show(name);                            
        }
    }

    if(reader.Name == "Initial_Position")
    {
        if (reader.GetAttribute("In_X") != null && reader.GetAttribute("In_Y") != null)
        {
            X1 = int.Parse(reader.GetAttribute("In_X"));
            Y1 = int.Parse(reader.GetAttribute("In_Y"));
        }
    }

    if (reader.Name == "Initial_Position")
    {
        if (reader.GetAttribute("Fin_X") != null && reader.GetAttribute("Fin_Y") != null)
        {
            X2 = int.Parse(reader.GetAttribute("Fin_X"));
            Y2 = int.Parse(reader.GetAttribute("Fin_Y"));
        }
    }
    //Position Initial_Position = new Position (X1,Y1);
    //Position Final_Position = new Position(X2, Y2);

    Pd[i]=new Pedestrian (name, X1, Y1, X2, Y2);
    Pd[i].Draw();
    i++;
}

Который может прочитать любой атрибут (в данном случае «имя«), но не может прочитать внутри узла, а затем взять атрибут (в этом случае внутри «Initial_Position«, а затем » In_X «).

Кроме того, строка Pd[i]=new Pedestrian (name, X1, Y1, X2, Y2);дает мне следующую ошибку :

System.IndexOutOfRangeException occurs. 
Additional Information : index over limits of matrix

3 ответа

  1. Убедитесь, что дают желаемый XML. убедитесь, что каждый тег XML имеет тег close,
    убедитесь, что <Pedestrian Name="Mother">имеет закрывающий тег.
    Затем проверьте X и Y перед выполнением

    Pd[i]=new Pedestrian (name, X1, Y1, X2, Y2);
    Pd[i].Draw();
    

    И посмотрите на загрузку строки XML в datatable .

  2. Почему бы вам не сделать это в LINQ to XML вместо этого. Это намного проще и код намного чище:

    using System.Xml.Linq;
    
    string xml = "<Simulation><Pedestrian Name='Mother'><Initial_Position In_X='3' In_Y='3' /><Final_Position><First Fin_X='6' Fin_Y='6' Time='2' /></Final_Position></Pedestrian></Simulation>";
    XDocument doc = XDocument.Parse(xml);
    
    foreach (XElement pedestrian in doc.Root.Elements("Pedestrian"))
    {
        XElement initialPosition = pedestrian.Element("Initial_Position");
    
        string name = pedestrian.Attribute("Name").Value;
        string x = initialPosition.Attribute("In_X").Value;
        string y = initialPosition.Attribute("In_Y").Value;
    
        Console.WriteLine("Name - {0}.X - {1}.Y - {2}", name, x, y);
    
    }
    
    Console.ReadKey();
    
  3. Вы могли бы использовать XDocumentи сделать это.

        XDocument doc = XDocument.Parse(input);
    
    
        var results = doc.Descendants("Pedestrian")
                         .Select(x=> 
                                 new Pedestrian() 
                                 {
                                     Name = x.Attribute("Name").Value, 
                                     X1 = int.Parse(x.Element("Initial_Position").Attribute("In_X").Value),
                                     Y1 = int.Parse(x.Element("Initial_Position").Attribute("In_Y").Value),
                                     X2 = int.Parse(x.Element("Final_Position").Element("First") .Attribute("Fin_X").Value),
                                     Y2 = int.Parse(x.Element("Final_Position").Element("First") .Attribute("Fin_Y").Value)
                                 });
    

    Выход

     Name  : Mother
     X1    : 3
     X2    : 6
     Y1    : 3
     Y2    : 6
    

    Проверить это Demo