I have been trying off and on to populate an object from an XML string. I am a complete nincompoop at Linq, so I decide to kind of combine Linq and XPath… Here is the sad attempt…
public static PatientClass getDataFromXMLintoPOCO(string xml)
{
PatientClass patClass = null;
string xmlFromSvc = xml;
XDocument xDocument = XDocument.Parse(xmlFromSvc);
XElement elem = xDocument.Element("dataTemplateSpecification");
PatientClass template = (PatientClass)(from templates in 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.XPathSelectElement("elements/element[@name='PatientId']").Attribute("value").Value),
EMPIID = int.Parse(templates.XPathSelectElement("elements/element[@name='EMPIID']").Attribute("value").Value),
//public int PopulationPatientID { get; set; }
FirstName = templates.XPathSelectElement("elements/element[@name='FirstName']").Attribute("value").Value,
LastName = templates.XPathSelectElement("elements/element[@name='LastName']").Attribute("value").Value,
DateOfBirth = DateTime.Parse(templates.XPathSelectElement("elements/element[@name='DateOfBirth']").Attribute("value").Value),
Phone = templates.XPathSelectElement("elements/element[@name='Phone']").Attribute("value").Value,
HostpitalFinNumber = templates.XPathSelectElement("elements/element[@name='HostpitalFinNumber']").Attribute("value").Value,
AdminDate = DateTime.Parse(templates.XPathSelectElement("elements/element[@name='AdminDate']").Attribute("value").Value),
MRNType = templates.XPathSelectElement("elements/element[@name='MRNType']").Attribute("value").Value,
MRN = templates.XPathSelectElement("elements/element[@name='MRN']").Attribute("value").Value,
PatientRoomPhone = templates.XPathSelectElement("elements/element[@name='PatientRoomPhone']").Attribute("value").Value,
DischargeDateTime = DateTime.Parse(templates.XPathSelectElement("elements/element[@name='DischargeDateTime']").Attribute("value").Value),
DischargeDisposition = templates.XPathSelectElement("elements/element[@name='DischargeDisposition']").Attribute("value").Value,
DischargeTo = templates.XPathSelectElement("elements/element[@name='DischargeTo']").Attribute("value").Value,
DischargeAdvocateCall = templates.XPathSelectElement("elements/element[@name='DischargeAdvocateCall']").Attribute("value").Value.ToCharArray()[0],
Payor = templates.XPathSelectElement("elements/element[@name='Payor']").Attribute("value").Value,
HomeHealthCareAccepted = templates.XPathSelectElement("elements/element[@name='HomeHealthCareAccepted']").Attribute("value").Value.ToCharArray()[0],
SafeLandingAccepted = templates.XPathSelectElement("elements/element[@name='SafeLandingAccepted']").Attribute("value").Value.ToCharArray()[0],
PCPName = templates.XPathSelectElement("elements/element[@name='PCPName']").Attribute("value").Value,
PCPPhone = templates.XPathSelectElement("elements/element[@name='PCPPhone']").Attribute("value").Value,
SpecialistName = templates.XPathSelectElement("elements/element[@name='SpecialistName']").Attribute("value").Value,
SpecialistPhone = templates.XPathSelectElement("elements/element[@name='SpecialistPhone']").Attribute("value").Value,
PCPAppointmentDateTime = DateTime.Parse(templates.XPathSelectElement("elements/element[@name='PCPAppointmentDateTime']").Attribute("value").Value),
PCPAppointmentLocation = templates.XPathSelectElement("elements/element[@name='PCPAppointmentLocation']").Attribute("value").Value,
SpecialistAppointmentDateTime = DateTime.Parse(templates.XPathSelectElement("elements/element[@name='SpecialistAppointmentDateTime']").Attribute("value").Value),
SpecialistAppointmentLocation = templates.XPathSelectElement("elements/element[@name='SpecialistAppointmentLocation']").Attribute("value").Value,
CompletedPathway = templates.XPathSelectElement("elements/element[@name='CompletedPathway']").Attribute("value").Value.ToCharArray()[0],
CompletedPathwayReason = templates.XPathSelectElement("elements/element[@name='CompletedPathwayReason']").Attribute("value").Value,
Comment = templates.XPathSelectElement("elements/element[@name='Comment']").Attribute("value").Value
}).AsEnumerable();
//return template != null ? template : null;
return patClass != null ? patClass : null;
}
}
The object that I am trying to fill is like so…
class PatientClass
{
public int Item_ID { get; set; }
public int PatientId { get; set; }
public int EMPIID { get; set; }
//public int PopulationPatientID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public string Phone { get; set; }
public string HostpitalFinNumber { get; set; }
public DateTime AdminDate { get; set; }
public string MRNType { get; set; }
public string MRN { get; set; }
public string PatientRoomPhone { get; set; }
public DateTime DischargeDateTime { get; set; }
public string DischargeDisposition { get; set; }
public string DischargeTo { get; set; }
public char DischargeAdvocateCall { get; set; }
public string Payor { get; set; }
public char HomeHealthCareAccepted { get; set; }
public char SafeLandingAccepted { get; set; }
public string PCPName { get; set; }
public string PCPPhone { get; set; }
public string SpecialistName { get; set; }
public string SpecialistPhone { get; set; }
public DateTime PCPAppointmentDateTime { get; set; }
public string PCPAppointmentLocation { get; set; }
public DateTime SpecialistAppointmentDateTime { get; set; }
public string SpecialistAppointmentLocation { get; set; }
public char CompletedPathway { get; set; }
public string CompletedPathwayReason { get; set; }
public string Comment { get; set; }
}
The XML is to massive and weildy. It strikes fear into the common man, that I can assure you. I cut out most of it just so it can appear readable…
<?xml version="1.0" encoding="utf-8"?>
<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" />
<validation>
<rules>
<rule id="r0" test="#element0.value == ''">
<fail>
<html>
<b>Patient ID is null, value must be present</b>
</html>
</fail>
</rule>
</rules>
</validation>
</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" />
<!--Patient/compositeID[./idType='populationPatientID']/id-->
<validation>
<rules>
<rule id="r1" test="#element1.value == ''">
<fail>
<html>
<b>EMPI ID is null, value must be present</b>
</html>
</fail>
</rule>
</rules>
</validation>
</element>
<element id="element2" name="EMPIID" display="EMPIID" dataType="String" visable="true" readOnly="true" value="">
<mapping path="//Template/TemplateData/ACOData/EMPI" />
<!--//Templates/Patient/sources/source/empi"/>-->
<validation>
<rules>
<rule id="r1" test="#element1.value == ''">
<fail>
<html>
<b>EMPI ID is null, value must be present</b>
</html>
</fail>
</rule>
</rules>
</validation>
</element>
<element id="element2" name="PRELOADMPACMRN" display="MPACMRN" dataType="String" visable="true" readOnly="true" value="">
<mapping path="//Template/Patient/sources/source/mpacmrn" />
<validation>
<rules>
<rule id="r1" test="#element1.value == ''">
<fail>
<html>
<b>EMPI ID is null, value must be present</b>
</html>
</fail>
</rule>
</rules>
</validation>
</element>
</elements>
<dataTypeSpecifications>
<dataTypeSpecification id="" baseType="KeyValuePair">
<dictionaryDefinition>
<item key="0" value="-SELECT-" />
<item key="1" value="YES" />
<item key="2" value="NO" />
</dictionaryDefinition>
</dataTypeSpecification>
</dataTypeSpecifications>
</template>
</templates>
</dataTemplateSpecification>
Apparently, I am getting a casting error of sorts. First question, there has got to be an easier cleaner way to do this than what I am doing right now. Any suggestions for cleaning this up. Also, Why am I getting a casting error? Any help given will be appreciated thanks.
Considering the complexity of your input XML document, I would expect that you will need a pretty complex piece of C# code to parse it and transform into the class you have given!
One thing I would point out is that your XPaths such as “elements/element[@name=’PatientId’]” can be converted into an equivalent Linq query as follows:
This doesn’t really make you code much simpler, but it does at least mean you are not mixing Linq and XPath.