views:

85

answers:

1
+1  Q: 

LINQ to XML Syntax

I've got a simple POCO class to hold data extracted from an XML file defined as follows:

public class Demographics
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string MiddleName { get; set; }
    public string Gender { get; set; }
}

I've got a fairly straight-forward XML file (or rather element in this case) to extract data from, defined as follows:

<patient determinerCode="INSTANCE">
    <name use="L">
     <given>John</given>
     <given qualifier="IN">Q.</given>
     <family>Public</family>
    </name>
    <administrativeGenderCode code="F" displayName="Female"/> 
</patient>

The challenge I'm having is getting the middle initial and/or first name into the correct properties in my class. As you can see, there are two given nodes inside the name node and the middle initial is designated by an "IN" attribute. Is there a simply LINQ syntax that I'm missing here, or do I need to query for all the given nodes and enumerate through them to properly place each node?

My code as it currently stands, looks like this:

private string GetInterfaceXmlData(XElement source)
{
     //Source in this context represents the "patient" element as you see in the example.
     //The NMSPC constant represents the namespace for this XML document which is not specifically displayed
     //in the XML example.
     Demographics currentDemo = new Demographics()
     {
      //I realize that this particular reference to FirstName is not optimal, as it may not actually
      //be the first "given" node under the name node, it's simply a place holder for now.
      FirstName = source.Element(NMSPC + "name").Element(NMSPC + "given").Value,
      LastName = source.Element(NMSPC + "name").Element(NMSPC + "family").Value,
      Gender=source.Element(NMSPC+"administrativeGenderCode").Attribute("code").Value,
     };
     XElement result = new XElement("XML");
     result.Add(new XElement("Demographics"));
     return result.ToString();
}
+5  A: 

How about:

// For the first name
source.Element(NMSPC + "name")
      .Elements(NMSPC + "given")
      .Where(element => element.Attribute("IN") == null)
      .First()

// For the initial
source.Element(NMSPC + "name")
      .Elements(NMSPC + "given")
      .Where(element => element.Attribute("IN") != null)
      .First()

EDIT: Query syntax is a bit awkward here. For the first version, it would be:

(from element in .Element(NMSPC + "name").Elements(NMSPC + "given")
where element.Attribute("IN") == null
select element).First()

I'd personally stick to dot notation for this.

Jon Skeet
OK, as I see this it seems a little obvious. I was a bit hung up on using query syntax which may have been my downfall. If you have time, would you mind dropping in a responce in that syntax? I'd like to see where I was going wrong there as well. As always, thanks very much Jon.
Steve Brouillard
Thanks again. I see your point about query syntax being awkward.
Steve Brouillard