I was wondering is there a way that I can use Linq to XML to get an array of objects out of an xml string... I am used to using XPath to do all of my dirty work, and Xpath seems so intuitive. But, I keep hearing about how great linq is and once you get it, then it makes you life much easier. The jury is still out on that one, but then again, I am not that great with Linq. Still learning. But suppose I have an object...
class PatientClass
{
//public int Item_ID { get; set; }
public int PatientId { get; set; }
public int EMPIID { get; set; }
}
Suppose I have another object...
public class TemplateModel
{
List<PatientACOModel> Template { set; get; }
}
which is simply a list of the first object...
suppose I have an xml document that looks like so...
<dataTemplateSpecification id="id1" name="name1" >
<templates xmlns="">
<template>
<elements>
<element id="element0" name="PatientId" display="Patient ID" dataType="String" visable="true" readOnly="false" value="4563">
<mapping path="//Template/TemplateData/ACOData/PATIENT_ID" />
</element>
<element id="element1" name="PopulationPatientID" display="Population Patient ID" dataType="String" visable="true" readOnly="true" enc="2098" value="6407">
<mapping path="//Template/TemplateData/ACOData/POPULATION_PATIENT_ID" />
</element>
<element id="element2" name="EMPIID" display="EMPIID" dataType="String" visable="true" readOnly="true" value="">
<mapping path="//Template/TemplateData/ACOData/EMPI" />
</element>
</elements>
</template>
<template>
<elements>
<element id="element0" name="PatientId" display="Patient ID" dataType="String" visable="true" readOnly="false" value="4563">
<mapping path="//Template/TemplateData/ACOData/PATIENT_ID" />
</element>
<element id="element1" name="PopulationPatientID" display="Population Patient ID" dataType="String" visable="true" readOnly="true" enc="2098" value="6407">
<mapping path="//Template/TemplateData/ACOData/POPULATION_PATIENT_ID" />
</element>
<element id="element2" name="EMPIID" display="EMPIID" dataType="String" visable="true" readOnly="true" value="">
<mapping path="//Template/TemplateData/ACOData/EMPI" />
</element>
</elements>
</template>
<template>
<elements>
<element id="element0" name="PatientId" display="Patient ID" dataType="String" visable="true" readOnly="false" value="4563">
<mapping path="//Template/TemplateData/ACOData/PATIENT_ID" />
</element>
<element id="element1" name="PopulationPatientID" display="Population Patient ID" dataType="String" visable="true" readOnly="true" enc="2098" value="6407">
<mapping path="//Template/TemplateData/ACOData/POPULATION_PATIENT_ID" />
</element>
<element id="element2" name="EMPIID" display="EMPIID" dataType="String" visable="true" readOnly="true" value="">
<mapping path="//Template/TemplateData/ACOData/EMPI" />
</element>
</elements>
</template>
</templates>
</dataTemplateSpecification>
You see, dataTemplateSpecification/templates/template would be an instance of the PatientClass that I have above. whereas dataTemplateSpecification/templates/ would be an instance of the TemplateModel object (a list of PatientClasses... I have them named PatientACOModel in the List, but they are essentially the same thing... one simply doesn't have as many variables as the other).
Now I use this to parse out a patient object...
IEnumerable<PatientClass> template = (IEnumerable<PatientClass>)(from templates in xDocument.Descendants("dataTemplateSpecification")//elem.XPathSelectElements(string.Format("//templates/template[./elements/element[@name=\"PopulationPatientID\"and @value='{0}' and @enc='{1}']]", "1", 0))
select new PatientClass
{
PatientId = int.Parse(templates.Descendants("element").Single(el => el.Attribute("name").Value=="PatientId").ToString()),//XPathSelectElement("elements/element[@name='PatientId']").Attribute("value").Value),
EMPIID = int.Parse(templates.Descendants("element").Single(el => el.Attribute("name").Value=="EMPIID").ToString()),//XPathSelectElement("elements/element[@name='EMPIID']").Attribute("value").Value),
}
It is currently returning null values, but I am working on that... But How could I get a list of these patients. I would probably need a super query to handle the list of stuff and sub query to get the Patient info right?
So something like this...
IEnumerable<TemplateModel> template = (IEnumerable<TemplateModel>)(from templates in elem.XPathSelectElements("//templates/template")
select new TemplateModel
{
TemplateModel =
(from pat in templates
select new PatientClass
{
PatientId = int.Parse(templates.XPathSelectElement("elements/element[@name='PatientId']").Attribute("value").Value),
EMPIID = int.Parse(templates.XPathSelectElement("elements/element[@name='EMPIID']").Attribute("value").Value),
)
}
That would seem logical to me. But perhaps I don't understand the basis of Linq