XML Parsing - Read a Simple XML File and Retrieve Values
Solution 1
Easy way to parse the xml is to use the LINQ to XML
for example you have the following xml file
<library>
<track id="1" genre="Rap" time="3:24">
<name>Who We Be RMX (feat. 2Pac)</name>
<artist>DMX</artist>
<album>The Dogz Mixtape: Who's Next?!</album>
</track>
<track id="2" genre="Rap" time="5:06">
<name>Angel (ft. Regina Bell)</name>
<artist>DMX</artist>
<album>...And Then There Was X</album>
</track>
<track id="3" genre="Break Beat" time="6:16">
<name>Dreaming Your Dreams</name>
<artist>Hybrid</artist>
<album>Wide Angle</album>
</track>
<track id="4" genre="Break Beat" time="9:38">
<name>Finished Symphony</name>
<artist>Hybrid</artist>
<album>Wide Angle</album>
</track>
<library>
For reading this file, you can use the following code:
public void Read(string fileName)
{
XDocument doc = XDocument.Load(fileName);
foreach (XElement el in doc.Root.Elements())
{
Console.WriteLine("{0} {1}", el.Name, el.Attribute("id").Value);
Console.WriteLine(" Attributes:");
foreach (XAttribute attr in el.Attributes())
Console.WriteLine(" {0}", attr);
Console.WriteLine(" Elements:");
foreach (XElement element in el.Elements())
Console.WriteLine(" {0}: {1}", element.Name, element.Value);
}
}
Solution 2
I usually use XmlDocument
for this. The interface is pretty straight forward:
var doc = new XmlDocument();
doc.LoadXml(xmlString);
You can access nodes similar to a dictionary:
var tasks = doc["Tasks"];
and loop over all children of a node.
Solution 3
Are you familiar with the DataSet
class?
The DataSet
can also load
XML documents and you may find it easier to iterate.
http://msdn.microsoft.com/en-us/library/system.data.dataset.readxml.aspx
DataSet dt = new DataSet();
dt.ReadXml(@"c:\test.xml");
Solution 4
Try XmlSerialization
try this
[Serializable]
public class Task
{
public string Name{get; set;}
public string Location {get; set;}
public string Arguments {get; set;}
public DateTime RunWhen {get; set;}
}
public void WriteXMl(Task task)
{
XmlSerializer serializer;
serializer = new XmlSerializer(typeof(Task));
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream, Encoding.Unicode);
serializer.Serialize(writer, task);
int count = (int)stream.Length;
byte[] arr = new byte[count];
stream.Seek(0, SeekOrigin.Begin);
stream.Read(arr, 0, count);
using (BinaryWriter binWriter=new BinaryWriter(File.Open(@"C:\Temp\Task.xml", FileMode.Create)))
{
binWriter.Write(arr);
}
}
public Task GetTask()
{
StreamReader stream = new StreamReader(@"C:\Temp\Task.xml", Encoding.Unicode);
return (Task)serializer.Deserialize(stream);
}
Lucidity
Updated on July 18, 2020Comments
-
Lucidity almost 4 years
I've written a Task Scheduling program for learning purposes. Currently I'm saving the scheduled tasks just as plain text and then parsing it using Regex. This looks messy (code wise) and is not very coherent.
I would like to load the scheduled tasks from an XML file instead, I've searched quite a bit to find some solutions but I couldn't get it to work how I wanted.
I wrote an XML file structured like this to store my data in:
<Tasks> <Task> <Name>Shutdown</Name> <Location>C:/WINDOWS/system32/shutdown.exe</Location> <Arguments>-s -f -t 30</Arguments> <RunWhen> <Time>8:00:00 a.m.</Time> <Date>18/03/2011</Date> <Days> <Monday>false</Monday> <Tuesday>false</Tuesday> <Wednesday>false</Wednesday> <Thursday>false</Thursday> <Friday>false</Friday> <Saturday>false</Saturday> <Sunday>false</Sunday> <Everyday>true</Everyday> <RunOnce>false</RunOnce> </Days> </RunWhen> <Enabled>true</Enabled> </Task> </Tasks>
The way I'd like to parse the data is like so:
- Open Tasks.xml
- Load the first Task tag.
- In that task retrieve the values of the Name, Location and Arguments tags.
- Then open the RunWhen tag and retrieve the values of the Time and Date tags.
- After that open the Days tag and retrieve the value of each individual tag within.
- Retrieve the value of Enabled.
- Load the next task and repeat steps 3 -> 7 until all the Task tags in Tasks have been parsed.
I'm very sure you can do it this way I just can't work it out as there are so many different ways to do things in XML I got a bit overwhelmed. But what I've go so far is that I would most likely be using XPathDocument and XPathNodeIterator right?
If someone can show me an example or explain to me how this would be done I would be very happy.
-
John Saunders about 11 years-1: DataTable cannot load all XML, only XML that matches the pattern of a relational database.
-
WraithNath about 11 years@JohnSaunders - Care to elaborate? I just tried the above code with the xml file in question and reads it no problem
-
John Saunders about 11 yearsJust what I said.
DataSet
can't handle arbitrary XML. It can only handle XML that maps to a "relational" structure. Many "normal" things you might want to use with XML won't work withDataSet
. For instance,<root><parent1><child/></parent1><parent2><child/></parent2></root>
. A relational table can't have two parents, so this won't work withDataSet
. -
WraithNath about 11 years@JohnSaunders - Thanks, so although it works for the above xml, it might not work when there are multiple different tasks (full xml file). will have to try and remember that if I run into problems using it again in the future
-
VenerableAgents about 9 yearsFor those who want to copy/paste this code, you'll also need to add "using System.Xml.Linq;"
-
Moeez about 5 yearsCan you please see one of my question regarding the xml response?
-
Moeez about 5 yearsCan you please see one of my question regarding the xml response?