user1934500
user1934500

Reputation: 51

Getting multiple attribute values under node

I'm having a hard time parsing the nodes that have both attributes and descendants.

I need to get into customer node and parse everything below it to a value for use on a web page.

var contacts = from c in xdoc.Descendants("contact")
               select new Contact
               {              
                   Email = (string)c.Element("email"),
                   HomePhone = (string)c.Element("phone").Attribute("type") // ?
               };

And my XML:

    <customer>
          <contact>
            <name part="first">Rick</name>
            <name part="last">Smith</name>
            <email>[email protected]</email>
            <phone type="home">2299998989</phone>
            <phone type="work">2298887878</phone>
            <phone type="cell">2297778878</phone>
            <address type="home">
              <street line="1">4001 Coleman Rd</street>
              <street line="2">Ste. 99</street>
              <city>Tempe</city>
              <regioncode>AZ</regioncode>
              <postalcode>43444</postalcode>
            </address>
          </contact>
          <comments>Customer comments</comments>
        </customer>

        <vendor>
          <contact>
            <name part="full" type="salesperson">Joe Smith</name>
          </contact>
        </vendor>

Upvotes: 0

Views: 987

Answers (2)

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236318

XDocument xdoc = XDocument.Load(path_to_xml);
var customers = 
    from c in xdoc.Descendants("customer")
    let contact = c.Element("contact")        
    let names = contact.Elements("name")
    let phones = contact.Elements("phone")
    let address = contact.Element("address")
    let streets = address.Elements("street")
    select new Customer {
        Contact = new Contact {
            FirstName = (string)names.SingleOrDefault(n => (string)n.Attribute("part") == "first"),
            LastName = (string)names.SingleOrDefault(n => (string)n.Attribute("part") == "last"),
            Email = (string)contact.Element("email"),
            HomePhone = (string)phones.SingleOrDefault(p => (string)p.Attribute("type") == "home"),
            CellPhone = (string)phones.SingleOrDefault(p => (string)p.Attribute("type") == "cell"),
            WorkPhone = (string)phones.SingleOrDefault(p => (string)p.Attribute("type") == "work"),
            Address = new Address {
                    Type = (string)address.Attribute("type"),
                    StreetLine1 = (string)streets.SingleOrDefault(s => (int)s.Attribute("line") == 1),
                    StreetLine2 = (string)streets.SingleOrDefault(s => (int)s.Attribute("line") == 2),
                    City = (string)address.Element("city"),
                    RegionCode = (string)address.Element("regioncode"),
                    PostalCode = (string)address.Element("postalcode")
                }
        },
        Comments = (string)c.Element("comments")
    };

You need following classes to hold parsed data:

public class Customer
{
    public Contact Contact { get; set; }
    public string Comments { get; set; }
}

public class Contact
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string HomePhone { get; set; }
    public string WorkPhone { get; set; }
    public string CellPhone { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public string Type { get; set; }
    public string StreetLine1 { get; set; }
    public string StreetLine2 { get; set; }
    public string City { get; set; }
    public string RegionCode { get; set; }
    public string PostalCode { get; set; }
}

Upvotes: 2

MarcinJuraszek
MarcinJuraszek

Reputation: 125660

To get home phone number you should use that:

HomePhone = (string)c.Elements("phone").SingleOrDefault(e => (string)e.Attribute("type") == "home");

Upvotes: 1

Related Questions