You know you're a geek when it's not even 7AM but you've already spent half the morning reading a whitepaper about Microsoft's plans to integrate XML and relational query language functionality into the .NET Framework with Linq.  C# 3.0 is going to be hot.

Like it's forefather X# Xen Cω, XLinq does an amazing job of integrating XML directly into the Common Language Runtime and the C#/VB.NET programming languages. Below are some code samples to whet your appetite until I can get around to writing an article later this year

  1. Creating an XML document

    XDocument contactsDoc = 
        
    new XDocument(
         
    new XDeclaration("1.0", "UTF-8", "yes"),
         
    new XComment("XLinq Contacts XML Example"),
         
    new XProcessingInstruction("MyApp", "123-44-4444"),
            
    new XElement("contacts",
             
    new XElement("contact",
               
    new XElement("name","Patrick Hines"),                                       
                
    new XElement("phone", "206-555-0144"),
                
    new XElement("address",
                
    new XElement("street1", "123 Main St"),
                 
    new XElement("city", "Mercer Island"),
                 
    new XElement("state", "WA"),
                 
    new XElement("postal", "68042")
                            )
                          )
                        )
                      );

  2. Creating an XML element in the "http://example.com" namespace

    XElement contacts = new XElement("{http://example.com}contacts");

  3. Loading an XML element from a file

    XElement contactsFromFile = XElement.Load(@"c:\myContactList.xml");

  4. Writing out an array of Person objects as an XML file

    class Person {
            public string Name;
            public string[] PhoneNumbers;
    }

    var persons = new [] { new Person
                                                                {Name=
    "Patrick Hines"
    ,
                                   PhoneNumbers =
    new string
    []
                                                                                        {
    "206-555-0144", "425-555-0145"
    }
                                   },
                          
    new Person {Name="Gretchen Rivas"
    ,
                                       PhoneNumbers =
    new string
    []
                                                                                        {
    "206-555-0163"
    }
                                   }
                          };

    XElement contacts = new XElement("contacts",
                           
    from p in persons
                           
    select new XElement("contact"
    ,
                               
    new XElement("name"
    , p.Name),
                               
    from ph in
    p.PhoneNumbers
                               
    select new XElement("phone"
    , ph)
                            )

                        );

    Console.WriteLine(contacts);

  5. Print out all the element nodes that are children of the <contact> element

    foreach (x in contact.Elements()) {
               
    Console.WriteLine(x);
    }

  6. Print all the <phone> elements that are children of the <contact> element

    foreach (x in contact.Elements("phone")) {
               
    Console
    .WriteLine(x);
    }

  7. Adding a <phone> element as a child of the <contact> element

    XElement mobilePhone = new XElement("phone", "206-555-0168");
    contact.Add(mobilePhone);

  8. Adding a <phone> element as a sibling of another <phone> element

    XElement mobilePhone = new XElement("phone", "206-555-0168");
    XElement firstPhone = contact.Element("phone"
    );
    firstPhone.AddAfterThis(mobilePhone);

  9. Adding an <address> element as a child of the <contact> element

    contact.Add(new XElement("address",
                  
    new XElement("street", "123 Main St"
    ),
                  
    new XElement("city", "Mercer Island"
    ),
                  
    new XElement("state", "WA"
    ),
                  
    new XElement("country", "USA"
    ),
                  
    new XElement("postalCode", "68042"
    )
                ));

  10. Deleting all <phone> elements under a <contact> element

    contact.Elements("phone").Remove();

  11. Delete all children of the <address> element which is a child of the <contact> element

    contacts.Element("contact").Element("address").RemoveContent();

  12. Replacing the content of the <phone> element under a <contact> element

    contact.Element("phone").ReplaceContent("425-555-0155");

  13. Alternate technique for replacing the content of the <phone> element under a <contact> element

    contact.SetElement("phone", "425-555-0155");

  14. Creating a contact element with attributes multiple phone number types

    XElement contact =
         
    new XElement("contact"
    ,
               
    new XElement("name", "Patrick Hines"
    ),
               
    new XElement("phone"
    ,
                     
    new XAttribute("type", "home")
    ,
                     
    "206-555-0144"
               
    ),
               
    new XElement("phone"
    ,
                     
    new XAttribute("type", "work")
    ,
                     
    "425-555-0145"
               
    )
          );

  15. Printing the value of the <phone> element whose type attribute has the value "home"

    foreach (p in contact.Elements("phone")) {
               
    if ((string)p.Attribute("type") == "home"
    )
                   
    Console.Write("Home phone is: " + (string
    )p);
       }

  16. Deleting the type attribute of the first <phone> element under the <contact> element

    contact.Elements("phone").First().Attribute("type").Remove();

  17. Transforming our original <contacts> element to a new <contacts> element containing a list of <contact> elements whose children are <name> and <phoneNumbers>

    new XElement("contacts",
         
    from c in contacts.Elements("contact"
    )
         
    select new XElement("contact"
    ,
                c.Element(
    "name"
    ),
               
    new XElement("phoneNumbers", c.Elements("phone"
    ))
          )
    );

  18. Retrieving the names of all the contacts from Washington, sorted alphabetically 

    from    c in contacts.Elements("contact")
    where   (
    string) c.Element("address").Element("state") ==
    "WA"
    orderby (string) c.Element("name"
    )
    select  (
    string) c.Element("name");

All examples were taken from the XLinq: .NET Language Integrated Query for XML Data  white paper.


 

Thursday, 15 September 2005 17:26:04 (GMT Daylight Time, UTC+01:00)
It reminds me of when C++ came out and everyone thought overloading was the coolest new thing, then they abused it and everyone created like new languages out of the operators e.g. record++ would go to the next record even though intuitively it means to increment the value of the record. With LINQ, things you can already do in the language can now be done in new exciting, and questionable ways. However, the typing and intellisense will be cool, and the fact that it is coming from the company that created the language sort of makes it more acceptable.
Ben Bryant
Thursday, 15 September 2005 18:23:58 (GMT Daylight Time, UTC+01:00)
XLinq is coolbeans. DLinq, however, has me worried. It seems to fly in the face of every single industry best practice... Ad-hoc queries vs. precompiled SProcs, tight coupling of the app logic to the DB schema, etc. Lets hope the team gets off their purist high horse and takes a more pragmatic approach to the issue.

And, btw, the layout of the code sample is a bit broken by the end of the right-hand navbar.
Friday, 16 September 2005 02:44:25 (GMT Daylight Time, UTC+01:00)
AOL!!!!

ME TOO!!!!11!!
a
Friday, 16 September 2005 06:14:25 (GMT Daylight Time, UTC+01:00)
I'm slightly dissapointed. The Xen syntax (with XML tags included) was a lot more intuitive. "new XElement" repeated forever just isn't right...

Does LINQ have the "first class XML" feature included but you just didn't use it in your sample or is it totally missing?
Nigel
Friday, 16 September 2005 14:32:02 (GMT Daylight Time, UTC+01:00)
Step 1 is about as verbose as it could be. The type casting is unfortunate but definitely understandable. If you have a schema, is the need for type-casting eliminated? Steo 18. is cool, though it could have been cooler if select were the first clause because it would make xml querying just that much more familiar to SQL people. In any case, I'm looking forward to the article!
Friday, 16 September 2005 23:18:06 (GMT Daylight Time, UTC+01:00)
Dude! you are supposed to use "XML Binding" for stuff like this. Just look at the ugly verbose code you had to write to spill out somebody's address in XML and think for yourself.
Saturday, 17 September 2005 07:50:37 (GMT Daylight Time, UTC+01:00)
MS got it almost right with XLinq. Much more intuitive and easy to use than the existing APIs. Makes me wonder they are dropping XPath altogether, though. Navigating with methods like Elements("contact") and Descendants("contact") is really cool. However, there should also be a method that allows the use of XPath expressions as well - like Nodes("contact/phone"). I guess the problem is asking for attributes, since they are no longer treated as nodes.
Also, what's with XML Literals being a VB thing only. Can't they be added to C# as well.
G Mladenov
Comments are closed.