0

I'm using an anonymous type to grab some XML data. All was going well until I ran across a section of XML where there can be 2 or 3 similar nodes. Like in the XML sample below there are 3 separate "Phones". My code was working fine when there was only ONE element that was possible to grab after following the "element path" I led it to. How can i grab a specific one? Or all 3 for that matter? Handling XML is still new to me and there seems to be soo many ways of handling it Searching the web for my exact need here didn't prove successful. Thanks.

var nodes = from node in doc.Elements("ClaimsSvcRs").Elements("ClaimDownloadRs")
            select new
                {
                    Phone1 = (string)node.Elements("Communications").Elements("PhoneInfo").Elements("PhoneNumber").FirstOrDefault(),
                    Phone2 = (string)node.Elements("Communications").Elements("PhoneInfo").Elements("PhoneNumber").FirstOrDefault(),
                };

The XML Code is

<?xml version="1.0" encoding="UTF-8"?>
<TEST>
   <ClaimsSvcRs>
      <ClaimDownloadRs>
          <Communications>
             <PhoneInfo>
                <PhoneTypeCd>Phone</PhoneTypeCd>
                <CommunicationUseCd>Home</CommunicationUseCd>
                <PhoneNumber>+1-715-5553944</PhoneNumber>
             </PhoneInfo>
             <PhoneInfo>
                <PhoneTypeCd>Phone</PhoneTypeCd>
                <CommunicationUseCd>Business</CommunicationUseCd>
                <PhoneNumber>+1-715-5552519</PhoneNumber>
             </PhoneInfo>
             <PhoneInfo>
                <PhoneTypeCd>Phone</PhoneTypeCd>
                <CommunicationUseCd>Cell</CommunicationUseCd>
                <PhoneNumber>+1-715-5551212</PhoneNumber>
             </PhoneInfo>
          </Communications>
     </ClaimDownloadRs>
   </ClaimsSvcRs>
</TEST>
JimDel
  • 4,309
  • 11
  • 54
  • 99
  • 1
    I haven't used xpath in a while so i'll let someone else stand in there... but there's a way to select a particular PhoneInfo object based upon its subelements. So if you knew whether you wanted Home or Business or Cell or whatever, you'd be able to select that particular PhoneInfo object. Otherwise if you wanted simple Phone1,2,3 and nulls where ok, use the Skip linq function. Phone2 = query.Skip(1).FirstOrDefault() – thewyzard Nov 11 '14 at 21:57
  • I'm not using XPath. I'm using XElement and LINQ. But I think you have me on the right track with the Skip extension method. More to come. – JimDel Nov 11 '14 at 22:33

2 Answers2

1

I haven't used xpath in a while so i'll let someone else stand in there... but there's a way to select a particular PhoneInfo object based upon its subelements. So if you knew whether you wanted Home or Business or Cell or whatever, you'd be able to select that particular PhoneInfo object. Otherwise if you wanted simple Phone1,2,3 and nulls where ok, use the Skip linq function. Phone2 = query.Skip(1).FirstOrDefault()

lol no worries ;) xpath can be intermixed in here, was my thought, and might be more elegant if your CommunicationUseCd fields were deterministic. Then you could have Home = ... and Work = ..., etc, instead of Phone1 & Phone2

The same could be accomplished by slipping a where clause into each your query lines

thewyzard
  • 312
  • 1
  • 6
  • Your right. If I change the "Phone2" to Phone2 = (string)node.Elements("Communications").Elements("PhoneInfo").Skip(1).Elements("‌​PhoneNumber").FirstOrDefault(), .... It works great! Thanks. – JimDel Nov 12 '14 at 00:03
0

If you're up for LINQ you can get all your elements in one go:

foreach(XElement phone in XDocument.Parse(xmlString).Descendants("PhoneInfo"))
{
    Console.WriteLine(phone.Element("PhoneNumber").Value);
    //etc
}

I find XDocument & LINQ a lot easier than XmlDocument & XPath, if you're okay with the alternative. There's more info on them here

Community
  • 1
  • 1
Jonesopolis
  • 25,034
  • 12
  • 68
  • 112