views:

1191

answers:

2

I'm saving 2-dimensional coordinates on an XML file with a structure similar to:

<?xml version="1.0" encoding="utf-8" ?> 
<grid>
<coordinate time="78">
<initial>540:672</initial> 
<final>540:672</final> 
</coordinate>
</grid>

I can open the XML file and read it via the XmlTextReader, but how do I loop through the coordinates specifically to retrieve both the time attribute and data between the initial and final nodes in some format similar to:

string initial = "540:672";
string final  = "540:672";
int time = 78;

New Code:

My New Code:

//Read the XML file.
XDocument xmlDoc = XDocument.Load("C:\\test.xml");

foreach (var coordinate in xmlDoc.Descendants("coordinate"))
{
    this.coordinates[this.counter][0] = coordinate.Attribute("time").Value;
    this.coordinates[this.counter][1] = coordinate.Element("initial").Value;
    this.coordinates[this.counter][2] = coordinate.Element("final").Value;
    this.counter++;
};

but now I get this error:
"Object reference not set to an instance of an object."


XML

<?xml version="1.0" encoding="utf-8"?>
<grid>
  <coordinate time="62">
    <initial>540:672</initial>
    <final>540:672</final>
  </coordinate>

  ...

  <coordinate time="46">
    <initial>176:605</initial>
    <final>181:617</final>
  </coordinate>
</grid>

Skipped a few coordinate tags to fit, but they all had the time attribute and initial/final subtags.


Globals

uint counter = 0;

        // Coordinates to be retrieved from the XML file.
        string[][] coordinates;
+6  A: 

You might want to check into something like Linq-to-XML:

XDocument coordinates = XDocument.Load("yourfilename.xml");

foreach(var coordinate in coordinates.Descendants("coordinate"))
{
    string time = coordinate.Attribute("time").Value;

    string initial = coordinate.Element("initial").Value;
    string final = coordinate.Element("final").Value;

    // do whatever you want to do with those items of information now
}

That should be a lot easier than using straight low-level XmlTextReader....

See here or here (or a great many other places) for introductions to Linq-to-XML.


UPDATE:

please try this code - if it works, and you get all the coordinates in that resulting list, then the Linq-to-XML code is fine:

Define a new helper class:

public class Coordinate
{
    public string Time { get; set; }
    public string Initial { get; set; }
    public string Final { get; set; }
}

and in your main code:

XDocument xdoc = XDocument.Load("C:\\test.xml");

List<Coordinate> list = new List<Coordinate>();

foreach (var coordinate in xdoc.Descendants("coordinate"))
{
    string time = coordinate.Attribute("time").Value;
    string initial = coordinate.Element("initial").Value;
    string final = coordinate.Element("final").Value;

    list.Add(new Coordinate { Time = time, Initial = initial, Final = final });
}

How does this list and its contents look like?? Do you get all the coordinates you're expecting??

marc_s
Seconded. I use XDocument/XElement wherever possible now, so much easier.
womp
What namespace do I use?
Gio Borje
@Gio: `using System.Xml.Linq;` available in .NET 3.5 and up
marc_s
I had it, I just forgot to reference it. Thanks all.
Gio Borje
+1. Linq2XML is a godsend for the casual XML-User.
Stephan Keller
"Object reference not set to an instance of an object."Help again?
Gio Borje
XDocument is fine to use provided you are parsing small XML.
Spence
Thanks, it works perfectly now.
Gio Borje
A: 

You could have used XmlSerialization to make the XML into a simple list of coordinate classes with a small amount of work, e.g.

    public class coordinate
    {
        [XmlAttribute]
        public int time;
        [XmlElement(ElementName="initial")]
        public string initial;
        [XmlElement(ElementName = "final")]
        public string final;

        public coordinate()
        {
            time = 0;
            initial = "";
            final = "";
        }
    }

    public class grid
    {
        [XmlElement(ElementName="coordinate", Type = typeof(coordinate))]
        public coordinate[] list;

        public grid()
        {
            list = new coordinate[0];
        }
    }     

Then in your code:

XmlReader r = new XmlReader.Create(...);
grid g = (grid) new XmlSerializer(typeof(grid)).Deserialize(r);
tyranid
I'm considering this, but I've never done serialization before.
Gio Borje