What is a good way to read this XML?
What is a good way to read this XML? Or maybe I can structure the XML differently.
What I want is the process to be the main thing and then you could have any number of related process to follow.
<Job>
<Process>*something.exe</Process>
<RelatedToProcess>*somethingelse.exe</RelatedToProcess>
<RelatedToProcess>*OneMorething.exe</RelatedToProcess>
</Job>
I am currently using a XmlNodeList and reading the innertext and then splitting the string on * but I know there has to be 开发者_JAVA技巧a better way.
I suggest you to use Linq To Xml. You can load your xml in XDocument
and then access each separate XElement
by name or path.
Try this console app:
class Program
{
public class Job
{
public string Process { get; set; }
public IList<string> RelatedProcesses { get; set; }
}
static void Main(string[] args)
{
var xml = "<Job>" +
"<Process>*something.exe</Process>" +
"<RelatedToProcess>*somethingelse.exe</RelatedToProcess>" +
"<RelatedToProcess>*OneMorething.exe</RelatedToProcess>" +
"</Job>";
var jobXml = XDocument.Parse(xml);
var jobs = from j in jobXml.Descendants("Job")
select new Job
{
Process = j.Element("Process").Value,
RelatedProcesses = (from r in j.Descendants("RelatedToProcess")
select r.Value).ToList()
};
foreach (var t in jobs)
{
Console.WriteLine(t.Process);
foreach (var relatedProcess in t.RelatedProcesses)
{
Console.WriteLine(relatedProcess);
}
}
Console.Read();
}
}
I like to use XmlSerializer
for simple tasks like this, as it results in significantly less code to process the XML. All you need is a simple class that maps to your XML, e.g.
public class Job
{
public string Process { get; set; }
[XmlElement("RelatedToProcess")]
public List<string> RelatedProcesses { get; set; }
}
You can then read the XML like this:
XmlSerializer serializer = new XmlSerializer(typeof(Job));
using (var reader = XmlReader.Create(@"d:\temp\test.xml"))
{
Job j = (Job)serializer.Deserialize(reader);
Console.WriteLine(j.Process);
Console.WriteLine(j.RelatedProcesses.Count);
j.RelatedProcesses.ForEach(p => Console.WriteLine(p));
}
you can use XDocument
and XElement
If you want the Process to be "main thing" I would recommend restructuring XML as
<Job>
<Process Name="*.something.exe">
<RelatedToProcess>*somethingelse.exe</RelatedToProcess>
<RelatedToProcess>*OneMorething.exe</RelatedToProcess>
</Process>
</Job>
This way you can easily get all child elements of "Process" element...And logically they relate (at least to me :)) Whether you use attribute or element is a matter of style...
XDocument for sure!
XDocument xDoc = XDocument.Load("Process.xml");
var process = from p in xDoc.Descendants("Process")
select p.Value;
var relatedProcess = from p in xDoc.Descendants("RelatedToProcess")
select p.Value;
Console.WriteLine("Process: {0}", process.ElementAtOrDefault(0).ToString());
foreach (var p in relatedProcess)
Console.WriteLine("RelatedToProcess: {0}", p);
The code will print:
Process: *something.exe
RelatedToProcess: *somethingelse.exe
RelatedToProcess: *OneMorething.exe
I would actually store it slightly different. Concept is that you create a "Process" complex type and then you reuse it within RelatedProcess and you can make name an attribute if desired.
<Job>
<Process>something.exe</Process>
<RelatedProcess>
<Process>
<Name>somethingelse.exe</Name>
</Process>
<Process>
<Name>OneMorething.exe
</Name>
</Process>
</RelatedProcess>
</Job>
That would allow for better growth. For instance if you decided to have recursive processeses i.e.:
<Job>
<Process>
<Name>something.exe</Name>
<RelatedProcess>
<Process>
<Name>somethingelse.exe</Name>
<RelatedProcess>
<Process>
<Name>recursive.exe</Name>
</Process>
</RelatedProcess>
</Process>
<Process>
<Name>OneMorething.exe</Name>
</Process>
</RelatedProcess>
</Process>
</Job>
Here is an XDocument example.. I did not show the recursive creation of processes because i wasn't sure if you wanted to use it.
string xml = "<Job>...xml here ";
XDocument doc = XDocument.Parse(xml);
var Processess = from process in doc.Elements("Job").Elements("Process")
select new
{
ProcessName = process.Element("Name"),
RelatedProcesses = (from rprocess in process.Elements("RelatedProcess").Elements("Process")
select new
{
ProcessName = rprocess.Element("Name")
}
).ToList()
};
Let me know if you have questions.
精彩评论