-
Parsing Xml
Hi all
Need a bit of help with some XML ( i am new to XML so not sure what i am doing)
i have used a httprequest to acquire the xml information i need but i believe it uses elements
note . this is not the file im using just an example.
<people>
<location>
<list name="ben" surname="gunn" location="peru" dwelling="house"/>
<list name="tom" surname="cruise" location="miami" dweliing="condo"/>
...
</location>
</people>
Code:
XmlTextWriter writer = new XmlTextWriter(Console.Out);
XmlDocument mydata = new XmlDocument();
mydata = GetData(xmlUrl); // pass the url for xml stream
XmlNode root = mydata.DocumentElement;
XmlNodeList elemList = root.ChildNodes;
IEnumerator ienum = elemList.GetEnumerator();
while (ienum.MoveNext())
{
XmlNode title = (XmlNode)ienum.Current;
if (title.HasChildNodes)
{
Console.Write(title.Name + Environment.NewLine);
Console.Write(title.FirstChild.Name + Environment.NewLine);
Console.Write(title.NodeType);
// dont really want the type but the first element i.e its name "name" and contents "ben"
}
Console.WriteLine(title.OuterXml);
}
so i basically want to be able to find the root, check each child and see if that child has any elements, if it has i want to parse them individually so i can see what the elements are and get their values.
the above will give me the root and i can compare to see whether it has any child info or not but hiow do i access the elements ?
i am not 100% with IENumerator but can see it is returning a count of some sort for looping through.
im sorry if this is vague, but as i said im new to XML at the moment.
thanks in advance.
-
You could use linq to sql.
-
it's pretty simple you're on the right track.
based on
Code:
<people>
<location>
<list name="ben" surname="gunn" location="peru" dwelling="house"/>
</location>
</people>
XmlDocument doc; // load with above
// doc.DocumentElement.Name == "people"
// doc.DocumentElement.ChildNodes.Count == 1
// doc.DocumentElement.ChildNodes[0].Name = "location"
// doc.DocumentElement.ChildNodes[0].ChildNodes.Count == 1
// doc.DocumentElement.ChildNodes[0].ChildNodes[0].Name == "list"
// doc.DocumentElement.ChildNodes[0].ChildNodes[0].Attributes.Count == 4
// doc.DocumentElement.ChildNodes[0].ChildNodes[0].Attributes[0].Name == "name"
// doc.DocumentElement.ChildNodes[0].ChildNodes[0].Attributes[0].Value == "ben"
-
I personally use xpath for most of my XML reading, but that's only a truly viable option if you know the structure of the XML file in advance. I'd probably use the XmlNode system if I had to parse arbitrary XML documents.
That is, it's really easy to do something like "I want to find the Resolution attribute under Options\Settings\Video".
Anyhow, this should work to list attributes:
Code:
private void ListAttributes(XmlNode node)
{
foreach(XmlAttribute att in node.Attributes)
{
Console.Write(att.Name + " = " + att.Value + Environment.NewLine);
}
}
-
thanks for the help, appreciated.
i had some time to play around with this today and came up with an alternative to your suggestions which does what i need.
assuming that the people.xml has been saved to a file.
XML file :
<people>
<location>
<list name="ben" surname="gunn" location="peru" dwelling="house"/>
<list name="tom" surname="cruise" location="miami" dweliing="condo"/>
</location>
</people>
Code:
String fname = "people.xml";
XmlDocument mypeople = new XmlDocument();
FileStream Fstream = null;
if (File.Exists(fname))
{
try
{
Fstream = new FileStream(fname,
FileMode.Open,
FileAccess.Read);
// Open the XML file
mypeople.Load(Fstream);
}
finally
{
Fstream.Close();
}
}
XmlNodeList people = mypeople.GetElementsByTagName("list");
int pad = 10; //pad spacing value
Console.WriteLine(" =-= People=-=");
Console.WriteLine(
"Name".PadRight(pad, '-') +
"Surname".PadRight(pad, '-') +
"Location".PadRight(pad, '-') +
"Dwelling".PadRight(pad, '-')
);
foreach (XmlNode attr in people)
{
Console.WriteLine(
"{0} {1} {2} {3} ",
attr.Attributes["name"].InnerText.PadLeft(pad,'-'),
attr.Attributes["surname"].InnerText.PadLeft(pad, '-'),
attr.Attributes["location"].InnerText.PadLeft(pad,'-'),
attr.Attributes["dwelling"].InnerText.PadLeft(pad,'-'),
);
}
Console.ReadKey();
}
ignore the pad statement was messing with alignment on console. but this does achieve the desired effect.
just have to get it into a gridview in ASP.net now :(
Hope this helps someone else out.
-
Oh, if you know the structure of the file and just want to read attributes in that fashion, you can easily do that with XPath.
Sample:
Code:
XPathDocument d = new XPathDocument("people.xml");
XPathNavigator root = d.CreateNavigator();
XPathNodeIterator listIter = root.Select("/people/location/list");
while (listIter.MoveNext())
{
string name = listIter.Current.Evaluate("string(@name)") as string;
string surname = listIter.Current.Evaluate("string(@surname)") as string;
string location = listIter.Current.Evaluate("string(@location)") as string;
string dwelling = listIter.Current.Evaluate("string(@dwelling)") as string;
}
XPath has a lot more advanced features as well, but this is a simple example.
-
So many ways to do the same thing ;)
Code:
XmlDocument peopleXmlDoc = new XmlDocument();
peopleXmlDoc.load("people.xml");
XmlNodeList peopleList = peopleXmlDoc.DocumentElement.SelectNodes("location/list");
foreach(XmlNode peopleNode in peopleList)
{
string name = peopleNode.Attributes["name"].InnerText;
}//foreach
-
yes i was fortunate enough to have pulled the file and checked the structure of the XML so i knew what the layout was.
I t seems to me, after returning to programming after a very log break that it is more about knowing what is available already and using it to its best abilities rather than reinventing the wheel every time.
It also seems that a lot of classes offer similar yet slightly different ways to do things and a few appear to carry certain limitations to make them viable in some scenarios. Very confusing.
but as said above
so many ways to do the same thing !
the most time consuming part for me is finding a way to do it and finding out theres a better ( easier) way :S
but even if only one person benefits from posts like this - i think it is worth asking the question :)