Reputation: 217
I have the following XML file. I am trying to read the startDate node of the dept element but don't want to read the "startDate" node of any of the rest of the child elements like "DeptRoles".
<dept operationalStatus="active" primaryRole="Admin" depChangeDate="20130420">
<startDate type="legal">20130401</startDate>
<endDate type="legal"></endDate>
<startDate type="operational">20130320</startDate>
<endDate type="operational"></endDate>
<DeptRoles>
<DeptRole name="Other dept" status="active">
<startDate type="legal">20130401</startDate>
<endDate type="legal"></endDate>
<startDate type="operational">20130320</startDate>
<endDate type="operational"/>
<isPrimary/>
</DeptRole>
</DeptRoles>
</dept>
This is my c# code. This code is also getting the DeptRole startDate element, which I dont want.
public static List<organisation> Getorgdata(string data)
{
List<organisation> listorgdata = new List<organisation>();
XmlReader xmlReader = XmlReader.Create(new StringReader(data));
while (xmlReader.Read())
{
if (xmlReader.NodeType == XmlNodeType.Element)
{
organisation record = new organisation();
if (xmlReader.HasAttributes && xmlReader.Name == "dept")
{
record.orgOperationalStatus = xmlReader.GetAttribute("operationalStatus");
record.orgLegalStatus = xmlReader.GetAttribute("legalStatus");
}
else if (xmlReader.Name == "name")
{
record.orgName = xmlReader.ReadElementString("name");
}
else if (xmlReader.Name == "startDate" || xmlReader.Name == "endDate")
{
if (xmlReader.GetAttribute("type") == "legal")
{
record.orgLegalStartDate = xmlReader.ReadElementString("startDate");
record.orgLegalEndDate = xmlReader.ReadElementString("endDate");
}
else if (xmlReader.GetAttribute("type") == "operational")
{
record.orgOperationalStartDate = xmlReader.ReadElementString("startDate");
record.orgOperationalEndDate = xmlReader.ReadElementString("endDate");
listorgdata.Add(record);
}
}
}
}
return listorgdata;
}
Upvotes: 0
Views: 98
Reputation: 614
Try this :
var readSpecific = from a in xd.Descendants("departments")
select new
{
LegalStartDate = a.Element("dept").Elements("startDate").First(cc => cc.Attribute("type").Value == "legal").Value,
LegalEndDate = a.Element("dept").Elements("endDate").First(cc => cc.Attribute("type").Value == "legal").Value,
OperationalStartDate = a.Element("dept").Elements("startDate").First(cc => cc.Attribute("type").Value == "operational").Value,
OperationEndDate = a.Elements("dept").Elements("endDate").First(cc => cc.Attribute("type").Value == "operational").Value
};
Upvotes: 0
Reputation: 28520
I would use LINQ to XML (as others have suggested). Below is sample code that somewhat matches your posted code - explanation of the code follows.
public static List<organisation> Getorgdata(string data)
{
List<organisation> listorgdata = new List<organisation>();
XDocument xDoc = XDocument.Parse(data);
listorgdata = xDoc.Root.Elements("dept")
.Select(x => new organisation()
{
orgOperationalStatus = (string)x.Attribute("operationalStatus"),
orgLegalStartDate = (string)x.Elements("startDate")
.Where(x1 => (string)x1.Attribute("type") == "legal")
.First(),
orgOperationalStartDate = (string)x.Elements("startDate")
.Where(x1 => (string)x1.Attribute("type") == "operational")
.First()
}).ToList();
return listorgdata;
}
The first thing the above code does is load the XML into an XDocument with the XDocument.Parse
method.
The query then parses the XML document and returns a list of populated organization
objects. It goes something like this.
<dept>
elements (and the child elements).<dept>
element, create a new instance of organisation
and assign the value of the "operationalStatus" attribute to the operationalStatus
property of organisation
. The (string)
cast will gracefully handle the situation where the specified attribute is not present.<startDate>
children of the <dept>
element, taking the first one that has an attribute "type" equal to "legal".IEnumerabale<T>
result to a list by calling the .ToList()
extension method.This may not be the most efficient, and it doesn't cover all the properties you have in your original code, but it should at least get you going in the right direction. For example, if you wanted to get the "primaryRole" attribute, you'd simply add the following line in the new organisation()
block:
orgPrimaryRole = (string)x.Attribute("primaryRole"),
If you need the data from <DeptRoles>
you can get that to, but it's a little more involved.
If you prefer query syntax over method syntax, it would look like this:
listorgdata = (from x in xDoc.Root.Elements("dept")
select new
{
orgOperationalStatus = (string)x.Attribute("operationalStatus"),
orgLegalStartDate = (from x1 in x.Elements("startDate")
where (string)x1.Attribute("type") == "legal"
select (string)x1).First(),
orgOperationalStartDate = (from x1 in x.Elements("startDate")
where (string)x1.Attribute("type") == "operational"
select (string)x1).First()
}).ToList();
Upvotes: 1
Reputation: 1
I'm not sure how to create a query that fits your needs exactly. Try to append this query to your needs. http://msdn.microsoft.com/en-us/library/bb387061.aspx contains some info on linq2xml queries
XmlReader xmlReader = XmlReader.Create(new StringReader(data));
XDocument d = XDocument.Load(xmlReader);
var startDates = from item in d.Root.Descendants()
where item.Name == "startDate" && item.Parent.Name == "dept" && item.Parent.Attribute("deptid").Value == "anynumber"
select item;
// iterate over the startDates and do your magic
Upvotes: 0
Reputation: 3265
If I Add CATALOG
<CATALOG>
<dept operationalStatus="active" primaryRole="Admin" depChangeDate="20130420">
<startDate type="legal">20130401</startDate>
<endDate type="legal"></endDate>
<startDate type="operational">20130320</startDate>
<endDate type="operational"></endDate>
<DeptRoles>
<DeptRole name="Other dept" status="active">
<startDate type="legal">20130401</startDate>
<endDate type="legal"></endDate>
<startDate type="operational">20130320</startDate>
<endDate type="operational"/>
<isPrimary/>
</DeptRole>
</DeptRoles>
</dept>
</CATALOG>
by using System.Xml.Linq; You can get Your List :
XElement myXML = XElement.Load(@"C:\Users\User\Desktop\myXML.xml");
var deptDescendantsList = (from ep in myXML.Descendants("dept")
select ep.Elements("startDate")).ToList();
Upvotes: 0