1
<SubTexture name="explosion0000.png" x="180" y="474" width="24" height="25"/>
<SubTexture name="explosion0001.png" x="422" y="609" width="30" height="30"/>
<SubTexture name="explosion0002.png" x="395" y="981" width="34" height="34"/>
<SubTexture name="explosion0003.png" x="354" y="981" width="39" height="39"/>

Above are four lines of an XML file from which I need to extract the information into a list. I need to read each line and use the strings and the values to do a specific task. To do this I use the code

    {
        XmlReader xmlReader = XmlReader.Create("D:/C#/GameAssets/Images/alienExplode/images/alienExplode.xml");
        while (xmlReader.Read())
        {
            Console.Write(xmlReader.Name);
            while (xmlReader.MoveToNextAttribute()) // Read the attributes.
                Console.Write(" " + xmlReader.Name + " = '" + xmlReader.Value + "' ");
            Console.WriteLine(" ");
        }
        Console.ReadKey(); // wait for keyboard input to exit
    }`

But i don't know how to get the values into a list so that I can read it, extract the data and use it. Can someone help?

emorphus
  • 550
  • 9
  • 20
  • 3
    *"read an xml file line by line"* the concept of a "line" does not exist in XML. It's useless to think about it in these terms, get it out of your head. What you want to do is *parse* the XML and process it element-by-element. – Tomalak Dec 10 '17 at 18:40
  • Ok. Can you please help me to do that with a few lines of sample code using the above xml? – emorphus Dec 10 '17 at 18:42
  • Is there a special reason why you use `XmlReader` or is it just the first thing you've tried? Also explain in a sentence or two what you want to happen or produce, exactly. – Tomalak Dec 10 '17 at 18:44
  • also your code does not display any efforts in regards to creating and Adding anything to a List google is something that you have at your finger tips with lots of code samples and examples.. have you executed an effective google search as well..? – MethodMan Dec 10 '17 at 18:48
  • I have been dabbling with code since 8 PM and now it is 12.15 (past midnight) and still I get only the "Subtexture" part printed to the console. I did not write the list add code here as it did not work. I am trying to use this info to build a list of image name and their size and positions to be used for an animation in a c# program. – emorphus Dec 10 '17 at 18:58
  • The best recommendation I can give is to ditch `XmlReader` in favor of `XmlDocument` with XPath, or LINQ. `XmlReader` is geared towards a problem you don't have, and is needlessly complex for what you want to do. – Tomalak Dec 10 '17 at 19:05

2 Answers2

3

Quick solution (but with a hack...)

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

namespace ConsoleApp
{
    class Program
    {
        static void Main (string[] args)
        {
            var xml = @"<SubTexture name=""explosion0000.png"" x=""180"" y=""474"" width=""24"" height=""25""/>
                        <SubTexture name=""explosion0001.png"" x=""422"" y=""609"" width=""30"" height=""30""/>
                        <SubTexture name=""explosion0002.png"" x=""395"" y=""981"" width=""34"" height=""34""/>
                        <SubTexture name=""explosion0003.png"" x=""354"" y=""981"" width=""39"" height=""39""/>";

            var xElement = XElement.Parse ("<rootHack>" + xml + "</rootHack>"); // XElement requires root element, so we need to use a hack

            var list = xElement.Elements ().Select (element => new MyClass
            {
                Name   = element.Attribute ("name").Value,
                X      = int.Parse (element.Attribute ("x").Value),
                Y      = int.Parse (element.Attribute ("y").Value),
                Width  = int.Parse (element.Attribute ("width").Value),
                Height = int.Parse (element.Attribute ("height").Value),

            }).ToList ();
        }
    }

    class MyClass
    {
        public string Name;
        public int X, Y, Width, Height;

        public override string ToString () => $"{Name}, X={X} Y={Y}, W={Width} H={Height}";
    }
}
apocalypse
  • 5,764
  • 9
  • 47
  • 95
2

I solved the above problem with the code below. The xml file used is here.

using System;
using System.Collections.Generic;
using System.Xml;

namespace ReadXMLfromFile
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {
        static bool addToFile = false;
        static List<List<string>> imageData = new List<List<string>>();

        static void Main(string[] args)
        {

            XmlReader xmlReader = XmlReader.Create("D:/C#/GameAssets/Images/alienExplode/images/alienExplode.xml");
            while (xmlReader.Read())
            {
                List<string> tempData = new List<string>();

                while (xmlReader.MoveToNextAttribute())
                {
                    Console.Write(xmlReader.Value + " ");
                    tempData.Add(xmlReader.Value);
                    Console.WriteLine("-----------------------------> adding data to tempList " + tempData.Count);
                    //Console.ReadKey();
                    addToFile = true; // get ready to write


                }
                if (addToFile)
                {
                    Console.WriteLine("adding tempList to Mainlist");
                    imageData.Add(tempData);

                    Console.WriteLine("----------------------------> imagedata " + imageData.Count);

                    addToFile = false;

                }

            }
            Console.WriteLine(imageData.Count);

            for (int i = 1; i <= imageData.Count - 1; i++)
            {
                for (int x = 0; x < imageData[i].Count; x++)
                {
                    Console.WriteLine(imageData[i][x]);
                }
            }
            Console.ReadKey(); // wait for keyboard input to exit
        }
    }
}

It was possible to read the xml file "line by line" as is demonstrated in this example. It may be due to the fact that this particular file has all the nodes in the same format except the first node.

The counter in the first for loop starts at 1 as I am avoiding the first entry which is the name of the image list.

Please correct me if I have done something wrong. I am still learning.

Community
  • 1
  • 1
emorphus
  • 550
  • 9
  • 20