Confused on reading attributes of an XML element.

S

sherifffruitfly

Hi,

I have an xml file with structured like this:

<?xml version="1.0" encoding="UTF-8"?>
<Soldiers>
<Soldier name="Billy Smith" rank="Private" serial="34" />

(a bunch more soldiers)

</Soldiers>

In my program, I have a struct:

public struct soldierStruct
{
public string name;
public string rank;
public string serial;
}

I would like to make a loop that reads however many XML-soldiers there
are into an ArrayList of struct-soldiers. I can come up with the
framework for it, it's just the reading attributes part that I don't
understand how to do. Can anyone help?

Thanks for any suggestions,

cdj

===============
Framework:

public ArrayList GetSoldiers()
{
ArrayList soldiers= new ArrayList();
soldiers.clear();

XmlTextReader reader = new XmlTextReader(path + filename);
reader.Read();
while (reader.Read())
{
soldierStruct sol;

//Stuff here to make sure the reader is
where
//it's supposed to be?????

sol.name = ????? //Need attribute help
somewhere around here
sol.rank = ??????
sol.serial = ??????

soldiers.add(sol)
}

return soldiers;
}
 
M

Mythran

sherifffruitfly said:
Hi,

I have an xml file with structured like this:

<?xml version="1.0" encoding="UTF-8"?>
<Soldiers>
<Soldier name="Billy Smith" rank="Private" serial="34" />

(a bunch more soldiers)

</Soldiers>

In my program, I have a struct:

public struct soldierStruct
{
public string name;
public string rank;
public string serial;
}

I would like to make a loop that reads however many XML-soldiers there
are into an ArrayList of struct-soldiers. I can come up with the
framework for it, it's just the reading attributes part that I don't
understand how to do. Can anyone help?

Thanks for any suggestions,

cdj

===============
Framework:

public ArrayList GetSoldiers()
{
ArrayList soldiers= new ArrayList();
soldiers.clear();

XmlTextReader reader = new XmlTextReader(path + filename);
reader.Read();
while (reader.Read())
{
soldierStruct sol;

//Stuff here to make sure the reader is
where
//it's supposed to be?????

sol.name = ????? //Need attribute help
somewhere around here
sol.rank = ??????
sol.serial = ??????

soldiers.add(sol)
}

return soldiers;
}

I know this may not help you, but hey, it just might be of some use to you.
You can try creating a typed dataset and using it's methods to save to an
xml string/file or load from an xml string/file. All the reading/parsing of
the xml file is internal to the dataset and you get your "name", "rank",
"serial", etc properties because it is a typed dataset.

Just thought you may like to try a slightly alternate but easier approach :)

HTH,
Mythran
 
M

Marc Gravell

XmlReader can be hard. Once you know your node is a Soldier (possibly using
ReadToFollowing) you
should be able to use e.g. sol.rank = reader.GetAttribute("rank");

I don't know if you are coming from a C++ background, but "class" may be
more appropriate than "struct" here, else you could end up with a lot of
problems; I recommend refreshing "value type" versus "reference type".

Additionally, note that this may fit the XmlSerializer very nicely - making
a few changes to fit standard C# naming (although I haven't switched to
properties), you may be able to just use:

[Serializable]
public class Soldier
{
[XmlAttribute("name")]
public string Name; // better as a property
[XmlAttribute("rank")]
public string Rank;
[XmlAttribute("serial")]
public string Serial;
}

And then deserialize the xml as an array of soldiers. Might need a little
tweaking, and I'm not going to bother tilling in blanks unless you are
genuinely interested in this option - but would also save you having to do
much to write them back as xml.

Marc
 
S

Samuel R. Neff

Each call to Read() will advance the reader to the next node. So you
wan to call Read and then test if the node you found is a soldier node
and if so then you call MoveToFirstAttribute to get the first
attribute, and then MoveToNextAttribute for the following attributes.

Here's a working example. HOWEVER, I would strongly suggest using
XmlSerializer instead of custom XML code. XmlSerializer is easier to
use and writes more efficient code than what I'm showing here.

HTH,

Sam


------------------------------------------------------------
We're hiring! B-Line Medical is seeking Mid/Sr. .NET
Developers for exciting positions in medical product
development in MD/DC. Work with a variety of technologies
in a relaxed team environment. See ads on Dice.com.



using System;
using System.Collections;
using System.IO;
using System.Xml;

namespace CommandTest
{
public class XmlTextReaderAttributes
{
public static void Test()
{
ArrayList soldiers = GetSoldiers();
foreach(soldierStruct sol in soldiers)
{
Console.WriteLine(sol);
}
}

public static ArrayList GetSoldiers()
{
ArrayList soldiers = new ArrayList();
soldiers.Clear();

StringReader text = new StringReader(
@"<?xml version='1.0' encoding='UTF-8'?>
<Soldiers>
<Soldier name='Billy Smith' rank='Private' serial='34' />
<Soldier name='John Jones' rank='General' serial='25' />
</Soldiers>");

XmlTextReader reader = new XmlTextReader(text);
reader.Read();
while (reader.Read())
{
if (reader.Name == "Soldier" &&
reader.MoveToFirstAttribute())
{
soldierStruct sol = new soldierStruct();

do
{
switch (reader.Name)
{
case "name":
sol.name = reader.Value;
break;

case "rank":
sol.rank = reader.Value;
break;

case "serial":
sol.serial = reader.Value;
break;
}
} while (reader.MoveToNextAttribute());

soldiers.Add(sol);
}
}

return soldiers;
}

public struct soldierStruct
{
public string name;
public string rank;
public string serial;

public override string ToString()
{
return rank + " " + name + ", " + serial;
}

}
}
}
 
T

Tom Porterfield

sherifffruitfly said:
Hi,

I have an xml file with structured like this:

<?xml version="1.0" encoding="UTF-8"?>
<Soldiers>
<Soldier name="Billy Smith" rank="Private" serial="34" />

(a bunch more soldiers)

</Soldiers>

In my program, I have a struct:

public struct soldierStruct
{
public string name;
public string rank;
public string serial;
}

I would like to make a loop that reads however many XML-soldiers there
are into an ArrayList of struct-soldiers. I can come up with the
framework for it, it's just the reading attributes part that I don't
understand how to do. Can anyone help?

Thanks for any suggestions,

cdj

===============
Framework:

public ArrayList GetSoldiers()
{
ArrayList soldiers= new ArrayList();
soldiers.clear();

XmlTextReader reader = new XmlTextReader(path + filename);
reader.Read();
while (reader.Read())
{
soldierStruct sol;

//Stuff here to make sure the reader is
where
//it's supposed to be?????

sol.name = ????? //Need attribute help
somewhere around here
sol.rank = ??????
sol.serial = ??????

soldiers.add(sol)
}

return soldiers;
}

XmlDocument xDoc = new XmlDocument();
xDoc.Load(reader);
XmlNodeList nodes = xDoc.SelectNodes("Soldiers/Soldier");
foreach (XmlNode node in nodes)
{
sol.name = node.Attributes["name"].InnerText;
sol.rank = node.Attributes["rank"].InnerText;
sol.serial = node.Attributes["serial"].InnerText;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Reading xml attributes 1

Top