<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Martin Honnen's blog </title><link>http://msmvps.com/blogs/martin_honnen/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Grouping with LINQ to XML</title><link>http://msmvps.com/blogs/martin_honnen/archive/2009/11/27/grouping-with-linq-to-xml.aspx</link><pubDate>Fri, 27 Nov 2009 15:20:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1742523</guid><dc:creator>Martin Honnen</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/martin_honnen/rsscomments.aspx?PostID=1742523</wfw:commentRss><comments>http://msmvps.com/blogs/martin_honnen/archive/2009/11/27/grouping-with-linq-to-xml.aspx#comments</comments><description>&lt;p&gt;One of the major improvements in &lt;a href="http://www.w3.org/TR/xslt20/"&gt;XSLT 2.0&lt;/a&gt; is &lt;a href="http://www.w3.org/TR/xslt20/#grouping"&gt;grouping&lt;/a&gt; where the xsl:for-each-group element supports four different grouping ways with group-by, group-starting-with, group-ending-with and group-adjacent. Unfortunately Microsoft does not support XSLT 2.0 thus if you need to group some XML input and don&amp;#39;t want to write XSLT 1.0 you will need to use third party XSLT 2.0 implementation like &lt;a href="http://saxon.sourceforge.net/"&gt;Saxon 9&lt;/a&gt; or &lt;a href="http://www.altova.com/altovaxml.html"&gt;AltovaXML tools&lt;/a&gt; or you will need to use the &lt;a href="http://msdn.microsoft.com/en-us/library/bb546139.aspx"&gt;grouping support in LINQ&lt;/a&gt; with &lt;a href="http://msdn.microsoft.com/en-us/library/bb387098.aspx"&gt;LINQ to XML&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this blog post I will look into solving &lt;a href="http://www.w3.org/TR/xslt20/#grouping-examples"&gt;the grouping examples in the XSLT 2.0 specification&lt;/a&gt; with LINQ to XML to find out whether/how LINQ to XML allows you to solve the same problems that group-by, group-starting-with, group-ending-with and group-adjacent in XSLT 2.0 allow you to solve.&lt;/p&gt;
&lt;p&gt;The first example is rather straightforward, the group-by in XSLT 2.0 can be &amp;quot;translated&amp;quot; into a group by in LINQ. So with cities.xml being&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;cities&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;city&lt;/span&gt; &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Milano&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;  &lt;span style="color:red;"&gt;country&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Italia&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;      &lt;span style="color:red;"&gt;pop&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;5&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;city&lt;/span&gt; &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Paris&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;   &lt;span style="color:red;"&gt;country&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;France&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;      &lt;span style="color:red;"&gt;pop&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;7&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;city&lt;/span&gt; &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;M&amp;uuml;nchen&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;country&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Deutschland&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;pop&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;4&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;city&lt;/span&gt; &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Lyon&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;    &lt;span style="color:red;"&gt;country&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;France&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;      &lt;span style="color:red;"&gt;pop&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;2&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;city&lt;/span&gt; &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Venezia&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;country&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Italia&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;      &lt;span style="color:red;"&gt;pop&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;1&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;cities&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;we can use the following C# code&lt;/p&gt;
&lt;pre&gt;            XDocument input = XDocument.Load(&lt;span style="color:#a31515;"&gt;@&amp;quot;cities.xml&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            XDocument output = &lt;span style="color:blue;"&gt;new&lt;/span&gt; XDocument(&lt;br /&gt;                &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;table&amp;quot;&lt;/span&gt;,&lt;br /&gt;                    &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;tr&amp;quot;&lt;/span&gt;,&lt;br /&gt;                        &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;th&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;Position&amp;quot;&lt;/span&gt;),&lt;br /&gt;                        &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;th&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;Country&amp;quot;&lt;/span&gt;),&lt;br /&gt;                        &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;th&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;List of Cities&amp;quot;&lt;/span&gt;),&lt;br /&gt;                        &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;th&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;Population&amp;quot;&lt;/span&gt;),&lt;br /&gt;                        (&lt;span style="color:blue;"&gt;from&lt;/span&gt; city &lt;span style="color:blue;"&gt;in&lt;/span&gt; input.Root.Elements(&lt;span style="color:#a31515;"&gt;&amp;quot;city&amp;quot;&lt;/span&gt;)&lt;br /&gt;                         &lt;span style="color:blue;"&gt;group&lt;/span&gt; city &lt;span style="color:blue;"&gt;by&lt;/span&gt; (&lt;span style="color:blue;"&gt;string&lt;/span&gt;)city.Attribute(&lt;span style="color:#a31515;"&gt;&amp;quot;country&amp;quot;&lt;/span&gt;))&lt;br /&gt;                        .Select((g, i) =&amp;gt;&lt;br /&gt;                            &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;tr&amp;quot;&lt;/span&gt;,&lt;br /&gt;                                &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;td&amp;quot;&lt;/span&gt;, i + 1),&lt;br /&gt;                                &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;td&amp;quot;&lt;/span&gt;, g.Key),&lt;br /&gt;                                &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;td&amp;quot;&lt;/span&gt;, &lt;span style="color:blue;"&gt;string&lt;/span&gt;.Join(&lt;span style="color:#a31515;"&gt;&amp;quot;, &amp;quot;&lt;/span&gt;, g.Select(c =&amp;gt; (&lt;span style="color:blue;"&gt;string&lt;/span&gt;)c.Attribute(&lt;span style="color:#a31515;"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;)).ToArray())),&lt;br /&gt;                                &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;td&amp;quot;&lt;/span&gt;, g.Sum(c =&amp;gt; (&lt;span style="color:blue;"&gt;decimal&lt;/span&gt;)c.Attribute(&lt;span style="color:#a31515;"&gt;&amp;quot;pop&amp;quot;&lt;/span&gt;))))))));&lt;br /&gt;&lt;br /&gt;            output.Save(&lt;span style="color:#a31515;"&gt;@&amp;quot;cities.html&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;p&gt;to get cities.html as follows:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;table&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;tr&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;th&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Position&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;th&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;th&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Country&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;th&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;th&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;List of Cities&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;th&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;th&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Population&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;th&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;tr&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;1&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Italia&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Milano, Venezia&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;6&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;tr&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;tr&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;2&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;France&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Paris, Lyon&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;9&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;tr&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;tr&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;3&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Deutschland&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;M&amp;uuml;nchen&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;4&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;td&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;tr&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;tr&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;table&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;The only nuisance with the LINQ solution is that, to get the positional index, we need to switch from the query expression syntax to the functional syntax. And the index in XSLT/XPath is one based whereas in .NET is is zero based so we need to add one to get the same result.&lt;/p&gt;
&lt;p&gt;The second example is called &amp;quot;A Composite Grouping Key&amp;quot; as it wants to compute the average population value for each (country, name) combination. However the XSLT 2.0 solution then suggests to nest two xsl:for-each-group as XSLT 2.0 does not allow a grouping key containing of two separate values. LINQ however allows that so with LINQ to XML we can use the approach shown below. Assuming the XML input cities2.xml is&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;cities&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;city&lt;/span&gt; &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Milano&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;  &lt;span style="color:red;"&gt;country&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Italia&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;  &lt;span style="color:red;"&gt;year&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;1950&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;   &lt;span style="color:red;"&gt;pop&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;5.23&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;city&lt;/span&gt; &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Milano&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;  &lt;span style="color:red;"&gt;country&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Italia&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;  &lt;span style="color:red;"&gt;year&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;1960&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;   &lt;span style="color:red;"&gt;pop&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;5.29&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;city&lt;/span&gt; &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Padova&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;  &lt;span style="color:red;"&gt;country&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Italia&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;  &lt;span style="color:red;"&gt;year&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;1950&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;   &lt;span style="color:red;"&gt;pop&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;0.69&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;city&lt;/span&gt; &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Padova&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;  &lt;span style="color:red;"&gt;country&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Italia&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;  &lt;span style="color:red;"&gt;year&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;1960&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;   &lt;span style="color:red;"&gt;pop&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;0.93&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;city&lt;/span&gt; &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Paris&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;   &lt;span style="color:red;"&gt;country&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;France&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;  &lt;span style="color:red;"&gt;year&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;1951&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;   &lt;span style="color:red;"&gt;pop&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;7.2&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;city&lt;/span&gt; &lt;span style="color:red;"&gt;name&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Paris&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;   &lt;span style="color:red;"&gt;country&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;France&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;  &lt;span style="color:red;"&gt;year&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;1961&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;   &lt;span style="color:red;"&gt;pop&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;7.6&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;cities&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;then this C# code&lt;/p&gt;
&lt;pre&gt;            XDocument input = XDocument.Load(&lt;span style="color:#a31515;"&gt;@&amp;quot;cities2.xml&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            XDocument output = &lt;span style="color:blue;"&gt;new&lt;/span&gt; XDocument(&lt;br /&gt;                &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;div&amp;quot;&lt;/span&gt;,&lt;br /&gt;                    &lt;span style="color:blue;"&gt;from&lt;/span&gt; city &lt;span style="color:blue;"&gt;in&lt;/span&gt; input.Root.Elements(&lt;span style="color:#a31515;"&gt;&amp;quot;city&amp;quot;&lt;/span&gt;)&lt;br /&gt;                    &lt;span style="color:blue;"&gt;group&lt;/span&gt; city &lt;span style="color:blue;"&gt;by&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; { country = (&lt;span style="color:blue;"&gt;string&lt;/span&gt;)city.Attribute(&lt;span style="color:#a31515;"&gt;&amp;quot;country&amp;quot;&lt;/span&gt;), name = (&lt;span style="color:blue;"&gt;string&lt;/span&gt;)city.Attribute(&lt;span style="color:#a31515;"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;) } &lt;span style="color:blue;"&gt;into&lt;/span&gt; g&lt;br /&gt;                    &lt;span style="color:blue;"&gt;select&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;p&amp;quot;&lt;/span&gt;,&lt;br /&gt;                        g.Key.name + &lt;span style="color:#a31515;"&gt;&amp;quot;, &amp;quot;&lt;/span&gt; &lt;br /&gt;                        + g.Key.country + &lt;span style="color:#a31515;"&gt;&amp;quot;: &amp;quot;&lt;/span&gt; &lt;br /&gt;                        + g.Average(c =&amp;gt; (&lt;span style="color:blue;"&gt;decimal&lt;/span&gt;)c.Attribute(&lt;span style="color:#a31515;"&gt;&amp;quot;pop&amp;quot;&lt;/span&gt;)).ToString(CultureInfo.InvariantCulture))));&lt;br /&gt;&lt;br /&gt;            output.Save(&lt;span style="color:#a31515;"&gt;@&amp;quot;cities2.html&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;p&gt;produces the following output snippet:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Milano, Italia: 5.26&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Padova, Italia: 0.81&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Paris, France: 7.4&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The last group-by example in the XSLT 2.0 specification is called &amp;quot;Adding an Element to Several Groups&amp;quot;. Here XSLT&amp;#39;s &amp;quot;for-each-group group-by&amp;quot; excels as it simply allows the group-by expression to evaluate to a sequence of grouping keys where an item can then belong to several groups. With LINQ that is not possible so we need to follow a different approach, we first need to find the distinct keys, then for each distinct key we need to process the elements containing the key. So assuming the XML input is&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;titles&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;title&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;A Beginner&amp;#39;s Guide to &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ix&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Java&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ix&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;title&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;title&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Learning &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ix&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;XML&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ix&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;title&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;title&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Using &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ix&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;XML&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ix&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt; with &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ix&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Java&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;ix&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;title&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;titles&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;the following C# code &lt;/p&gt;
&lt;pre&gt;            XDocument input = XDocument.Load(&lt;span style="color:#a31515;"&gt;@&amp;quot;titles.xml&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            XDocument output = &lt;span style="color:blue;"&gt;new&lt;/span&gt; XDocument(&lt;br /&gt;                &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;div&amp;quot;&lt;/span&gt;,&lt;br /&gt;                    &lt;span style="color:blue;"&gt;from&lt;/span&gt; key &lt;span style="color:blue;"&gt;in&lt;/span&gt; input.Root.Elements(&lt;span style="color:#a31515;"&gt;&amp;quot;title&amp;quot;&lt;/span&gt;).Elements(&lt;span style="color:#a31515;"&gt;&amp;quot;ix&amp;quot;&lt;/span&gt;).Select(i =&amp;gt; i.Value).Distinct()&lt;br /&gt;                    &lt;span style="color:blue;"&gt;select&lt;/span&gt;&lt;br /&gt;                        (&lt;span style="color:blue;"&gt;new&lt;/span&gt; List&amp;lt;XElement&amp;gt;() {&lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;h2&amp;quot;&lt;/span&gt;, key)}).Union(&lt;br /&gt;                        &lt;span style="color:blue;"&gt;from&lt;/span&gt; title &lt;span style="color:blue;"&gt;in&lt;/span&gt; input.Root.Elements(&lt;span style="color:#a31515;"&gt;&amp;quot;title&amp;quot;&lt;/span&gt;)&lt;br /&gt;                        &lt;span style="color:blue;"&gt;where&lt;/span&gt; title.Elements(&lt;span style="color:#a31515;"&gt;&amp;quot;ix&amp;quot;&lt;/span&gt;).Any(ix =&amp;gt; (&lt;span style="color:blue;"&gt;string&lt;/span&gt;)ix == key)&lt;br /&gt;                        &lt;span style="color:blue;"&gt;select&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;p&amp;quot;&lt;/span&gt;, title.Value))));&lt;br /&gt;&lt;br /&gt;            output.Save(&amp;quot;titles.html);&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;produces the output fragment&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;h2&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Java&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;h2&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;A Beginner&amp;#39;s Guide to Java&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Using XML with Java&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;h2&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;XML&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;h2&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Learning XML&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Using XML with Java&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now let&amp;#39;s look at group-starting-with. With the sample input being&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;body&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;h2&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Introduction&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;h2&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;XSLT is used to write stylesheets.&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;XQuery is used to query XML databases.&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;h2&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;What is a stylesheet?&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;h2&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;A stylesheet is an XML document used to define a transformation.&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Stylesheets may be written in XSLT.&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;XSLT 2.0 introduces new grouping constructs.&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;body&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;the XSLT 2.0 solution has a template for the body element doing an &amp;lt;xsl:for-each-group select=&amp;quot;*&amp;quot; group-starting-with=&amp;quot;h2&amp;quot;&amp;gt; so it selects all child elements of the body and specifies a pattern &amp;#39;h2&amp;#39; to identity the element type starting a group. The LINQ grouping construct does not allow to follow this same approach but we can use a different approach instead: we process the &amp;#39;p&amp;#39; child elements and then group them by the immediately preceding &amp;#39;h2&amp;#39; sibling. We can select that with LINQ to XML as p.NodesBeforeSelf().OfType&amp;lt;XElement&amp;gt;().LastOrDefault(e =&amp;gt; e.Name == &amp;quot;h2&amp;quot;) which takes the preceding sibling nodes (NodesBeforeSelf()), restricts that to XElement element nodes (OfType&amp;lt;XElement&amp;gt;()) and then takes the last one in document order to have the name &amp;#39;h2&amp;#39;. With that approach the C# code looks as follows:&lt;/p&gt;
&lt;pre&gt;            XDocument input = XDocument.Load(&lt;span style="color:#a31515;"&gt;&amp;quot;input.xml&amp;quot;&lt;/span&gt;);&lt;br /&gt;            XDocument output = &lt;span style="color:blue;"&gt;new&lt;/span&gt; XDocument(&lt;br /&gt;                &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;chapter&amp;quot;&lt;/span&gt;,&lt;br /&gt;                    &lt;span style="color:blue;"&gt;from&lt;/span&gt; p &lt;span style="color:blue;"&gt;in&lt;/span&gt; input.Root.Elements(&lt;span style="color:#a31515;"&gt;&amp;quot;p&amp;quot;&lt;/span&gt;)&lt;br /&gt;                    &lt;span style="color:blue;"&gt;group&lt;/span&gt; p &lt;span style="color:blue;"&gt;by&lt;/span&gt; p.NodesBeforeSelf().OfType&amp;lt;XElement&amp;gt;().LastOrDefault(e =&amp;gt; e.Name == &lt;span style="color:#a31515;"&gt;&amp;quot;h2&amp;quot;&lt;/span&gt;) &lt;span style="color:blue;"&gt;into&lt;/span&gt; g&lt;br /&gt;                    &lt;span style="color:blue;"&gt;select&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;section&amp;quot;&lt;/span&gt;,&lt;br /&gt;                        &lt;span style="color:blue;"&gt;new&lt;/span&gt; XAttribute(&lt;span style="color:#a31515;"&gt;&amp;quot;title&amp;quot;&lt;/span&gt;, g.Key != &lt;span style="color:blue;"&gt;null&lt;/span&gt; ? g.Key.Value : &lt;span style="color:#a31515;"&gt;&amp;quot;&amp;quot;&lt;/span&gt;),&lt;br /&gt;                        &lt;span style="color:blue;"&gt;from&lt;/span&gt; p2 &lt;span style="color:blue;"&gt;in&lt;/span&gt; g&lt;br /&gt;                        &lt;span style="color:blue;"&gt;select&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;para&amp;quot;&lt;/span&gt;, p2.Value))));&lt;br /&gt;&lt;br /&gt;            output.Save(&lt;span style="color:#a31515;"&gt;&amp;quot;output.xml&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;and creates the following XML output:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;chapter&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;section&lt;/span&gt; &lt;span style="color:red;"&gt;title&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;Introduction&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;para&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;XSLT is used to write stylesheets.&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;para&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;para&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;XQuery is used to query XML databases.&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;para&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;section&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;section&lt;/span&gt; &lt;span style="color:red;"&gt;title&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;What is a stylesheet?&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;para&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;A stylesheet is an XML document used to define a transformation.&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;para&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;para&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Stylesheets may be written in XSLT.&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;para&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;para&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;XSLT 2.0 introduces new grouping constructs.&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;para&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;section&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;chapter&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;which is the same result the XSLT stylesheet creates. So basically as LINQ allows the grouping key to be an object we simply need to identity the XElement object (or generally the XNode object) starting a group and then we can make use the the LINQ group by construct.&lt;/p&gt;
&lt;p&gt;Not surprisingly a similar approach can be applied for the group-ending-with example. It has the following input&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;doc&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt; &lt;span style="color:red;"&gt;continued&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;yes&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Some text&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt; &lt;span style="color:red;"&gt;continued&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;yes&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;More text&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;    &lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Yet more text&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt; &lt;span style="color:red;"&gt;continued&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;yes&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Some words&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt; &lt;span style="color:red;"&gt;continued&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;yes&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;More words&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;    &lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Yet more words&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;        &lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;doc&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;and then has a template matching the &amp;#39;doc&amp;#39; element with an xsl:for-each-group select=&amp;quot;*&amp;quot; group-ending-with=&amp;quot;page[not(@continued=&amp;#39;yes&amp;#39;)]&amp;quot; meaning it processes all child element and provides a pattern to indentify the element node ending a group. With LINQ to XML we can select the &amp;#39;page&amp;#39; elements having the continued=&amp;quot;yes&amp;quot; attribute and group them by the immediately following sibling &amp;#39;page&amp;#39; element not having that attribute. That can be found using page.NodesAfterSelf().OfType&amp;lt;XElement&amp;gt;().FirstOrDefault(p =&amp;gt; !((string)p.Attribute(&amp;quot;continued&amp;quot;) == &amp;quot;yes&amp;quot;)) which selects the following sibling nodes, restricts that to XElement nodes and then takes the first in document order which does not have the continued=&amp;quot;yes&amp;quot; attribute. So the C# code looks as follows:&lt;/p&gt;
&lt;pre&gt;            XDocument input = XDocument.Load(&lt;span style="color:#a31515;"&gt;&amp;quot;input.xml&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            XDocument output = &lt;span style="color:blue;"&gt;new&lt;/span&gt; XDocument(&lt;br /&gt;                &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(input.Root.Name,&lt;br /&gt;                    &lt;span style="color:blue;"&gt;from&lt;/span&gt; page &lt;span style="color:blue;"&gt;in&lt;/span&gt; input.Root.Elements(&lt;span style="color:#a31515;"&gt;&amp;quot;page&amp;quot;&lt;/span&gt;)&lt;br /&gt;                    &lt;span style="color:blue;"&gt;where&lt;/span&gt; (&lt;span style="color:blue;"&gt;string&lt;/span&gt;)page.Attribute(&lt;span style="color:#a31515;"&gt;&amp;quot;continued&amp;quot;&lt;/span&gt;) == &lt;span style="color:#a31515;"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt;&lt;br /&gt;                    &lt;span style="color:blue;"&gt;group&lt;/span&gt; page &lt;span style="color:blue;"&gt;by&lt;/span&gt; page.NodesAfterSelf().OfType&amp;lt;XElement&amp;gt;().FirstOrDefault(p =&amp;gt; !((&lt;span style="color:blue;"&gt;string&lt;/span&gt;)p.Attribute(&lt;span style="color:#a31515;"&gt;&amp;quot;continued&amp;quot;&lt;/span&gt;) == &lt;span style="color:#a31515;"&gt;&amp;quot;yes&amp;quot;&lt;/span&gt;)) &lt;span style="color:blue;"&gt;into&lt;/span&gt; g&lt;br /&gt;                    &lt;span style="color:blue;"&gt;select&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;pageset&amp;quot;&lt;/span&gt;,&lt;br /&gt;                        &lt;span style="color:blue;"&gt;from&lt;/span&gt; page2 &lt;span style="color:blue;"&gt;in&lt;/span&gt; g&lt;br /&gt;                        &lt;span style="color:blue;"&gt;select&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(&lt;span style="color:#a31515;"&gt;&amp;quot;page&amp;quot;&lt;/span&gt;, page2.Value),&lt;br /&gt;                        g.Key)));&lt;br /&gt;&lt;br /&gt;            output.Save(&lt;span style="color:#a31515;"&gt;&amp;quot;output.xml&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;and produces the following output:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;doc&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;pageset&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Some text&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;More text&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Yet more text&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;pageset&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;pageset&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Some words&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;More words&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Yet more words&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;page&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;pageset&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;doc&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;Again, LINQ allowing us to have an object (e.g. XElement node) as the grouping key provides us with a way to use the LINQ group by to solve that problem.&lt;/p&gt;
&lt;p&gt;That leaves us with the group-adjacent XSLT example to be solved with LINQ to XML. As doing that looks to be harder and I am thinking of implementing that with an extension method I will end this article here and treat group-adjacent in another article.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1742523" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/LINQ+to+XML/default.aspx">LINQ to XML</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/XSLT+2.0/default.aspx">XSLT 2.0</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/grouping/default.aspx">grouping</category></item><item><title>Parsing XHTML documents with .NET 4.0 and XmlPreloadedResolver</title><link>http://msmvps.com/blogs/martin_honnen/archive/2009/11/08/parsing-xhtml-documents-with-net-4-0-and-xmlpreloadedresolver.aspx</link><pubDate>Sun, 08 Nov 2009 17:56:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1738448</guid><dc:creator>Martin Honnen</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/martin_honnen/rsscomments.aspx?PostID=1738448</wfw:commentRss><comments>http://msmvps.com/blogs/martin_honnen/archive/2009/11/08/parsing-xhtml-documents-with-net-4-0-and-xmlpreloadedresolver.aspx#comments</comments><description>&lt;p&gt;When &lt;a href="http://msmvps.com/blogs/martin_honnen/archive/2009/05/21/what-is-new-in-system-xml-in-net-4-0-visual-studio-2010.aspx"&gt;I looked at &amp;quot;What&amp;#39;s new in System.Xml in .NET 4.0/Visual Studio 2010&amp;quot; with the beta 1 release&lt;/a&gt; I presented an example that shows how parsing an XHTML document referencing one of the W3C XHTML 1.0 DTDs can be sped up by using the new XmlReaderSettings.DtdProcessing set to DtdProcessing.Ignore. The drawback I mentioned is that any referenced entity in the document would then throw an exception.&lt;/p&gt;
&lt;p&gt;What I overlooked at the time of the beta 1 release but I have found now in the recent beta 2 release is the new &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.resolvers.xmlpreloadedresolver(VS.100).aspx"&gt;class XmlPreloadedResolver&lt;/a&gt; in &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.resolvers(VS.100).aspx"&gt;System.Xml.Resolvers&lt;/a&gt;. It allows you to avoid any network access to the W3C&amp;#39;s server for the XHTML DTDs but nevertheless parse any XHTML document having entity references as it uses copies of those DTDs stored in an assembly deployed with the .NET framework.&lt;/p&gt;
&lt;p&gt;If I use that class with an adaption of the older example the code looks as follows:&lt;/p&gt;
&lt;pre&gt;            Stopwatch watch = &lt;span style="color:blue;"&gt;new&lt;/span&gt; Stopwatch();&lt;br /&gt;            XmlReaderSettings settings = &lt;span style="color:blue;"&gt;new&lt;/span&gt; XmlReaderSettings();&lt;br /&gt;            settings.DtdProcessing = DtdProcessing.Parse;&lt;br /&gt;            &lt;br /&gt;&lt;br /&gt;            &lt;span style="color:blue;"&gt;string&lt;/span&gt; xhtml = &lt;span style="color:#a31515;"&gt;@&amp;quot;&amp;lt;!DOCTYPE html &lt;br /&gt;     PUBLIC &amp;quot;&amp;quot;-//W3C//DTD XHTML 1.0 Strict//EN&amp;quot;&amp;quot;&lt;br /&gt;     &amp;quot;&amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;html xml:lang=&amp;quot;&amp;quot;en&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;Example&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;Price is: 100 &amp;amp;euro;&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;            watch.Start();&lt;br /&gt;            &lt;span style="color:blue;"&gt;using&lt;/span&gt; (XmlReader reader = XmlReader.Create(&lt;span style="color:blue;"&gt;new&lt;/span&gt; StringReader(xhtml), settings))&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color:blue;"&gt;while&lt;/span&gt; (reader.Read()) &lt;br /&gt;                {&lt;br /&gt;                    &lt;span style="color:blue;"&gt;if&lt;/span&gt; (reader.NodeType == XmlNodeType.Text)&lt;br /&gt;                    {&lt;br /&gt;                        Console.WriteLine(reader.Value);&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            watch.Stop(); ;&lt;br /&gt;            Console.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;First parse: elapsed time: {0}&amp;quot;&lt;/span&gt;, watch.Elapsed);&lt;br /&gt;&lt;br /&gt;            watch.Reset();&lt;br /&gt;&lt;br /&gt;            settings.XmlResolver = &lt;span style="color:blue;"&gt;new&lt;/span&gt; XmlPreloadedResolver(XmlKnownDtds.Xhtml10);&lt;br /&gt;&lt;br /&gt;            watch.Start();&lt;br /&gt;            &lt;span style="color:blue;"&gt;using&lt;/span&gt; (XmlReader reader = XmlReader.Create(&lt;span style="color:blue;"&gt;new&lt;/span&gt; StringReader(xhtml), settings))&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color:blue;"&gt;while&lt;/span&gt; (reader.Read())&lt;br /&gt;                {&lt;br /&gt;                    &lt;span style="color:blue;"&gt;if&lt;/span&gt; (reader.NodeType == XmlNodeType.Text)&lt;br /&gt;                    {&lt;br /&gt;                        Console.WriteLine(reader.Value);&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            watch.Stop(); ;&lt;br /&gt;            Console.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Second parse: elapsed time: {0}&amp;quot;&lt;/span&gt;, watch.Elapsed);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;Running that code here with Visual Studio 2010 Beta 2 in a virtual machine outputs numbers clearly showing the speed gained by parsing with the XmlPreloadedResolver:&lt;/p&gt;
&lt;p&gt;First parse: elapsed time: 00:00:04.6378648&lt;br /&gt;Second parse: elapsed time: 00:00:00.0441933&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1738448" width="1" height="1"&gt;</description></item><item><title>Exploiting covariance with LINQ to XML</title><link>http://msmvps.com/blogs/martin_honnen/archive/2009/06/01/exploiting-covariance-with-linq-to-xml.aspx</link><pubDate>Mon, 01 Jun 2009 04:32:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1693522</guid><dc:creator>Martin Honnen</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/martin_honnen/rsscomments.aspx?PostID=1693522</wfw:commentRss><comments>http://msmvps.com/blogs/martin_honnen/archive/2009/06/01/exploiting-covariance-with-linq-to-xml.aspx#comments</comments><description>&lt;p&gt;In my &lt;a href="http://msmvps.com/blogs/martin_honnen/archive/2009/05/31/exploiting-contravariance-with-linq-to-xml.aspx"&gt;last post&lt;/a&gt; I showed how the &lt;a href="http://msdn.microsoft.com/en-us/library/dd465120(VS.100).aspx"&gt;new contravariance feature in .NET 4.0/Visual Studio 2010 for type parameters of generic interfaces&lt;/a&gt; makes coding with LINQ to XML easier and more straightforward. In this post I will show how the &lt;a href="http://msdn.microsoft.com/en-us/library/9eekhta0(VS.100).aspx"&gt;covariance of the type parameter T of IEnumerable&amp;lt;T&amp;gt;&lt;/a&gt; also allows us to write LINQ to XML queries in a more straightforward way.&lt;/p&gt;
&lt;p&gt;Let&amp;#39;s assume we have the following XML document:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#a31515;"&gt;xml&lt;/span&gt; &lt;span style="color:red;"&gt;version&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;1.0&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;encoding&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;utf-8&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:blue;"&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;!--&lt;/span&gt;&lt;span style="color:green;"&gt; comment 1 --&amp;gt;&lt;br /&gt;  &amp;lt;foo&amp;gt;foo 1&amp;lt;/foo&amp;gt;&lt;br /&gt;  &amp;lt;bar&amp;gt;bar 1&amp;lt;/bar&amp;gt;&lt;br /&gt;  &amp;lt;!-- comment 2 --&amp;gt;&lt;br /&gt;  &amp;lt;foo&amp;gt;foo 2&amp;lt;/foo&amp;gt;&lt;br /&gt;  &amp;lt;bar&amp;gt;2&amp;lt;/bar&amp;gt;&lt;br /&gt;  &amp;lt;!-- comment 3 &lt;/span&gt;&lt;span style="color:blue;"&gt;--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;and we want to transform that document into a second one with the same root element having the same child nodes, except where all &amp;#39;bar&amp;#39; child elements of the &amp;#39;root&amp;#39; element node have been removed. So the result should look as follows:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#a31515;"&gt;xml&lt;/span&gt; &lt;span style="color:red;"&gt;version&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;1.0&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;encoding&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;utf-8&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:blue;"&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;!--&lt;/span&gt;&lt;span style="color:green;"&gt; comment 1 --&amp;gt;&lt;br /&gt;  &amp;lt;foo&amp;gt;foo 1&amp;lt;/foo&amp;gt;&lt;br /&gt;  &amp;lt;!-- comment 2 --&amp;gt;&lt;br /&gt;  &amp;lt;foo&amp;gt;foo 2&amp;lt;/foo&amp;gt;&lt;br /&gt;  &amp;lt;!-- comment 3 &lt;/span&gt;&lt;span style="color:blue;"&gt;--&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;A first attempt to achieve that with LINQ to XML could look as follows:&lt;/p&gt;
&lt;pre&gt;            XDocument doc1 = XDocument.Load(&lt;span style="color:#a31515;"&gt;@&amp;quot;XMLFile1.xml&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            XDocument doc2 =&lt;br /&gt;                &lt;span style="color:blue;"&gt;new&lt;/span&gt; XDocument(&lt;br /&gt;                    &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(doc1.Root.Name,&lt;br /&gt;                        doc1&lt;br /&gt;                        .Root&lt;br /&gt;                        .Nodes()&lt;br /&gt;                        .Except(&lt;br /&gt;                            doc1&lt;br /&gt;                            .Root&lt;br /&gt;                            .Elements(&lt;span style="color:#a31515;"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;))));&lt;br /&gt;&lt;br /&gt;            doc2.Save(Console.Out);&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;So we create a new XDocument with a new root XElement having the same name as the Root of the first XDocument where all child nodes except of the &amp;#39;bar&amp;#39; child elements are copied. &lt;/p&gt;
&lt;p&gt;Looks nice and straightforward only if you try to compile that with Visual Studio 2008/.NET 3.5 you get the following error: &amp;quot;Argument &amp;#39;2&amp;#39;: cannot convert from &amp;#39;System.Collections.Generic.IEnumerable&amp;lt;System.Xml.Linq.XElement&amp;gt;&amp;#39; to &amp;#39;System.Collections.Generic.IEnumerable&amp;lt;System.Xml.Linq.XNode&amp;gt;&amp;#39;&amp;quot;. &lt;/p&gt;
&lt;p&gt;The problem is that the Nodes() call returns an IEnumerable&amp;lt;XNode&amp;gt; and then the following Except() call also needs an IEnumerable&amp;lt;XNode&amp;gt; as its argument while Elements(&amp;quot;bar&amp;quot;) gives us an IEnumerable&amp;lt;XElement&amp;gt;. With generic interfaces being invariant in .NET 3.5 we can&amp;#39;t pass that IEnumerable&amp;lt;XElement&amp;gt; in for an IEnumerable&amp;lt;XNode&amp;gt;, although XElement is a class derived from XNode.&lt;/p&gt;
&lt;p&gt;As a workaround we can first cast the IEnumerable&amp;lt;XElement&amp;gt; to an IEnumerable&amp;lt;XNode&amp;gt;:&lt;/p&gt;
&lt;pre&gt;            XDocument doc1 = XDocument.Load(&lt;span style="color:#a31515;"&gt;@&amp;quot;XMLFile1.xml&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            XDocument doc2 =&lt;br /&gt;                &lt;span style="color:blue;"&gt;new&lt;/span&gt; XDocument(&lt;br /&gt;                    &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(doc1.Root.Name,&lt;br /&gt;                        doc1&lt;br /&gt;                        .Root&lt;br /&gt;                        .Nodes()&lt;br /&gt;                        .Except(&lt;br /&gt;                            doc1&lt;br /&gt;                            .Root&lt;br /&gt;                            .Elements(&lt;span style="color:#a31515;"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;)&lt;br /&gt;                            .Cast&amp;lt;XNode&amp;gt;())));&lt;br /&gt;&lt;br /&gt;            doc2.Save(Console.Out);&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;That way it compiles fine and produces the wanted result with .NET 3.5, only it seems desirable that you would not need that Cast&amp;lt;XNode&amp;gt;() call.&lt;/p&gt;
&lt;p&gt;The good news is that starting with .NET 4.0 the type parameter T of IEnumerable&amp;lt;T&amp;gt; is covariant meaning where an IEnumerable&amp;lt;T&amp;gt; of a certain type T is expected we can always pass in an IEnumerable&amp;lt;T2&amp;gt; where T2 is type derived from T, as in our example where XElement is a subclass of XNode (or subsubclass to be precise).&lt;/p&gt;
&lt;p&gt;Thus with .NET 4.0 the following compiles and works fine:&lt;/p&gt;
&lt;pre&gt;            XDocument doc1 = XDocument.Load(&lt;span style="color:#a31515;"&gt;@&amp;quot;XMLFile1.xml&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            XDocument doc2 =&lt;br /&gt;                &lt;span style="color:blue;"&gt;new&lt;/span&gt; XDocument(&lt;br /&gt;                    &lt;span style="color:blue;"&gt;new&lt;/span&gt; XElement(doc1.Root.Name,&lt;br /&gt;                        doc1&lt;br /&gt;                        .Root&lt;br /&gt;                        .Nodes()&lt;br /&gt;                        .Except(&lt;br /&gt;                            doc1&lt;br /&gt;                            .Root&lt;br /&gt;                            .Elements(&lt;span style="color:#a31515;"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;))));&lt;br /&gt;&lt;br /&gt;            doc2.Save(Console.Out);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1693522" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/Visual+Studio+2010/default.aspx">Visual Studio 2010</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/LINQ+to+XML/default.aspx">LINQ to XML</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/Except/default.aspx">Except</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/Covariance/default.aspx">Covariance</category></item><item><title>Exploiting contravariance with LINQ to XML</title><link>http://msmvps.com/blogs/martin_honnen/archive/2009/05/31/exploiting-contravariance-with-linq-to-xml.aspx</link><pubDate>Sun, 31 May 2009 04:35:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1693493</guid><dc:creator>Martin Honnen</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/martin_honnen/rsscomments.aspx?PostID=1693493</wfw:commentRss><comments>http://msmvps.com/blogs/martin_honnen/archive/2009/05/31/exploiting-contravariance-with-linq-to-xml.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd233054(VS.100).aspx"&gt;Covariance and contravariance for generic interfaces are new features in C# and VB.NET&lt;/a&gt; in Visual Studio 2010 respectively the .NET framework 4.0. Generic interfaces like IEnumerable&amp;lt;T&amp;gt; or IEqualityComparer&amp;lt;T&amp;gt; in the .NET framework 4.0 use these new features. Starting with .NET 4.0 the type parameter T in &lt;a href="http://msdn.microsoft.com/en-us/library/ms132151(VS.100).aspx"&gt;IEqualityComparer&amp;lt;T&amp;gt;&lt;/a&gt; is contravariant. That can make coding with LINQ to XML easier, as the class &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.linq.xnodeequalitycomparer(VS.100).aspx"&gt;XNodeEqualityComparer&lt;/a&gt; implements IEqualityComparer&amp;lt;XNode&amp;gt; where XNode is a common base class for other LINQ to XML classes like XElement.&lt;/p&gt;
&lt;p&gt;Let&amp;#39;s look at an example. Assume we have the following XML document&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color:#a31515;"&gt;xml&lt;/span&gt; &lt;span style="color:red;"&gt;version&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;1.0&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;encoding&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;utf-8&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:blue;"&gt;?&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;items&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;item&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;a&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;1&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;item&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;item&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;b&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;2&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;item&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;item&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;a&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;1&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;item&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;item&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;c&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;3&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;item&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;item&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;c&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;      &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;3&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;item&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;items&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;and we want to use LINQ to XML to extract distinct items where we use XNodeEqualityComparer to compare the &amp;#39;item&amp;#39; elements in the XML document.&lt;/p&gt;
&lt;p&gt;You could be tempted to try it as follows:&lt;/p&gt;
&lt;pre&gt;            XDocument doc = XDocument.Load(&lt;span style="color:#a31515;"&gt;&amp;quot;XMLFile1.xml&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            var distinctItems =&lt;br /&gt;                doc&lt;br /&gt;                .Root&lt;br /&gt;                .Element(&lt;span style="color:#a31515;"&gt;&amp;quot;items&amp;quot;&lt;/span&gt;)&lt;br /&gt;                .Elements(&lt;span style="color:#a31515;"&gt;&amp;quot;item&amp;quot;&lt;/span&gt;)&lt;br /&gt;                .Distinct(&lt;span style="color:blue;"&gt;new&lt;/span&gt; XNodeEqualityComparer())&lt;br /&gt;                .Select(i =&amp;gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; { foo = (&lt;span style="color:blue;"&gt;string&lt;/span&gt;)i.Element(&lt;span style="color:#a31515;"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;), bar = (&lt;span style="color:blue;"&gt;int&lt;/span&gt;)i.Element(&lt;span style="color:#a31515;"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;) });&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (var item &lt;span style="color:blue;"&gt;in&lt;/span&gt; distinctItems)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine(item);&lt;br /&gt;            }&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;but with .NET 3.5 that does not compile, complaining &amp;quot;Instance argument: cannot convert from &amp;#39;System.Collections.Generic.IEnumerable&amp;lt;System.Xml.Linq.XElement&amp;gt;&amp;#39; to &amp;#39;System.Collections.Generic.IEnumerable&amp;lt;System.Xml.Linq.XNode&amp;gt;&amp;#39;&amp;quot; on the Distinct(new XNodeEqualityComparer()) call. That happens because Elements(&amp;quot;item&amp;quot;) gives us an IEnumerable&amp;lt;XElement&amp;gt; and subsequently the Distinct method wants an IEqualityComparer&amp;lt;XElement&amp;gt; to be passed in while we only pass in an IEqualityComparer&amp;lt;XNode&amp;gt;. &lt;/p&gt;
&lt;p&gt;With .NET 3.5 to work around that problem we first have to cast IEnumerable&amp;lt;XElement&amp;gt; up to IEnumerable&amp;lt;XNode&amp;gt; before we call Distinct(new XNodeEqualityComparer()) and then down again after the Distinct() call:&lt;/p&gt;
&lt;pre&gt;            XDocument doc = XDocument.Load(&lt;span style="color:#a31515;"&gt;&amp;quot;XMLFile1.xml&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            var distinctItems =&lt;br /&gt;                doc&lt;br /&gt;                .Root&lt;br /&gt;                .Element(&lt;span style="color:#a31515;"&gt;&amp;quot;items&amp;quot;&lt;/span&gt;)&lt;br /&gt;                .Elements(&lt;span style="color:#a31515;"&gt;&amp;quot;item&amp;quot;&lt;/span&gt;)&lt;br /&gt;                .Cast&amp;lt;XNode&amp;gt;()&lt;br /&gt;                .Distinct(&lt;span style="color:blue;"&gt;new&lt;/span&gt; XNodeEqualityComparer())&lt;br /&gt;                .Cast&amp;lt;XElement&amp;gt;()&lt;br /&gt;                .Select(i =&amp;gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; { foo = (&lt;span style="color:blue;"&gt;string&lt;/span&gt;)i.Element(&lt;span style="color:#a31515;"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;), bar = (&lt;span style="color:blue;"&gt;int&lt;/span&gt;)i.Element(&lt;span style="color:#a31515;"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;) });&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (var item &lt;span style="color:blue;"&gt;in&lt;/span&gt; distinctItems)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine(item);&lt;br /&gt;            }&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;That compiles fine and nicely returns only distinct items:&lt;/p&gt;
&lt;p&gt;{ foo = a, bar = 1 }&lt;br /&gt;{ foo = b, bar = 2 }&lt;br /&gt;{ foo = c, bar = 3 }&lt;/p&gt;
&lt;p&gt;With .NET 4.0 however the type parameter T of IEqualityComparer is contravariant meaning if we have a method expecting an IEqualityComparer&amp;lt;XElement&amp;gt; it suffices to use a base type of XElement like XNode and thus with .NET 4.0 our original attempt compiles and runs fine:&lt;/p&gt;
&lt;pre&gt;            XDocument doc = XDocument.Load(&lt;span style="color:#a31515;"&gt;&amp;quot;XMLFile1.xml&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            var distinctItems =&lt;br /&gt;                doc&lt;br /&gt;                .Root&lt;br /&gt;                .Element(&lt;span style="color:#a31515;"&gt;&amp;quot;items&amp;quot;&lt;/span&gt;)&lt;br /&gt;                .Elements(&lt;span style="color:#a31515;"&gt;&amp;quot;item&amp;quot;&lt;/span&gt;)&lt;br /&gt;                .Distinct(&lt;span style="color:blue;"&gt;new&lt;/span&gt; XNodeEqualityComparer())&lt;br /&gt;                .Select(i =&amp;gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; { foo = (&lt;span style="color:blue;"&gt;string&lt;/span&gt;)i.Element(&lt;span style="color:#a31515;"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;), bar = (&lt;span style="color:blue;"&gt;int&lt;/span&gt;)i.Element(&lt;span style="color:#a31515;"&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;) });&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (var item &lt;span style="color:blue;"&gt;in&lt;/span&gt; distinctItems)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine(item);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1693493" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/Visual+Studio+2010/default.aspx">Visual Studio 2010</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/LINQ+to+XML/default.aspx">LINQ to XML</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/IEqualityComparer_2600_lt_3B00_T_2600_gt_3B00_/default.aspx">IEqualityComparer&amp;lt;T&amp;gt;</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/Contravariance/default.aspx">Contravariance</category></item><item><title>What is new in System.Xml in .NET 4.0/Visual Studio 2010</title><link>http://msmvps.com/blogs/martin_honnen/archive/2009/05/21/what-is-new-in-system-xml-in-net-4-0-visual-studio-2010.aspx</link><pubDate>Thu, 21 May 2009 07:21:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1693044</guid><dc:creator>Martin Honnen</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/martin_honnen/rsscomments.aspx?PostID=1693044</wfw:commentRss><comments>http://msmvps.com/blogs/martin_honnen/archive/2009/05/21/what-is-new-in-system-xml-in-net-4-0-visual-studio-2010.aspx#comments</comments><description>&lt;p&gt;Beta 1 of the .NET framework 4.0 and of Visual Studio 2010 has been released a few days ago. Although the &lt;a href="http://msdn.microsoft.com/en-us/library/dd409230(VS.100).aspx"&gt;&amp;quot;What&amp;#39;s new&amp;quot; document&lt;/a&gt; does not list any new features in System.Xml or LINQ to XML I am browsing through the documentation to find new features or changes in APIs.&lt;/p&gt;
&lt;p&gt;So far I have found the following:&lt;/p&gt;
&lt;p&gt;With LINQ to XML the &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.linq.saveoptions(VS.100).aspx"&gt;SaveOptions enumeration&lt;/a&gt; has a new flag named OmitDuplicateNamespaces. That is particularly useful with VB.NET XML literals as using them you might end up with more namespace declaration attributes as you want resulting in superfluous namespace declarations on child or descendant elements when you save/serialize a LINQ to XML XDocument or XElement.&lt;/p&gt;
&lt;p&gt;Here is an example in VB.NET with .NET 3.5:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;Imports&lt;/span&gt; System&lt;br /&gt;&lt;span style="color:blue;"&gt;Imports&lt;/span&gt; System.Xml.Linq&lt;br /&gt;&lt;span style="color:blue;"&gt;Imports&lt;/span&gt; &amp;lt;xmlns=&lt;span style="color:#a31515;"&gt;&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;Module&lt;/span&gt; Module1&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;Sub&lt;/span&gt; Main()&lt;br /&gt;        &lt;span style="color:blue;"&gt;Dim&lt;/span&gt; html &lt;span style="color:blue;"&gt;As&lt;/span&gt; XElement = _&lt;br /&gt;        &amp;lt;html&amp;gt;&lt;br /&gt;            &amp;lt;head&amp;gt;&lt;br /&gt;                &amp;lt;title&amp;gt;Example&amp;lt;/title&amp;gt;&lt;br /&gt;            &amp;lt;/head&amp;gt;&lt;br /&gt;            &amp;lt;body&amp;gt;&lt;br /&gt;            &amp;lt;/body&amp;gt;&lt;br /&gt;        &amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;        html.&amp;lt;body&amp;gt;(0).Add(GetParagraphs())&lt;br /&gt;&lt;br /&gt;        html.Save(Console.Out)&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;Function&lt;/span&gt; GetParagraphs() &lt;span style="color:blue;"&gt;As&lt;/span&gt; IEnumerable(Of XElement)&lt;br /&gt;        &lt;span style="color:blue;"&gt;Dim&lt;/span&gt; ps() &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;String&lt;/span&gt; = {&lt;span style="color:#a31515;"&gt;&amp;quot;Paragraph 1.&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;Paragraph 2.&amp;quot;&lt;/span&gt;}&lt;br /&gt;        &lt;span style="color:blue;"&gt;Return&lt;/span&gt; (From p &lt;span style="color:blue;"&gt;In&lt;/span&gt; ps &lt;span style="color:blue;"&gt;Select&lt;/span&gt; &amp;lt;p&amp;gt;&amp;lt;%= p %&amp;gt;&amp;lt;/p&amp;gt;)&lt;br /&gt;    &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Function&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Module&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;Its output is as follows:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;html&lt;/span&gt; &lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://www.w3.org/1999/xhtml&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;head&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;title&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Example&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;title&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;head&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;body&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt; &lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://www.w3.org/1999/xhtml&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Paragraph 1.&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt; &lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://www.w3.org/1999/xhtml&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Paragraph 2.&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;body&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;html&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, the namespace declarations on the &amp;#39;p&amp;#39; elements are redundant as the namespace is already defined on the &amp;#39;html&amp;#39; root element.&lt;/p&gt;
&lt;p&gt;With .NET 4.0 and the SaveOptions.OmitDuplicateNamespaces flag you can avoid them as follows:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;Imports&lt;/span&gt; System&lt;br /&gt;&lt;span style="color:blue;"&gt;Imports&lt;/span&gt; System.Xml.Linq&lt;br /&gt;&lt;span style="color:blue;"&gt;Imports&lt;/span&gt; &amp;lt;xmlns=&lt;span style="color:#a31515;"&gt;&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;Module&lt;/span&gt; Module1&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;Sub&lt;/span&gt; Main()&lt;br /&gt;        &lt;span style="color:blue;"&gt;Dim&lt;/span&gt; html &lt;span style="color:blue;"&gt;As&lt;/span&gt; XElement = _&lt;br /&gt;        &amp;lt;html&amp;gt;&lt;br /&gt;            &amp;lt;head&amp;gt;&lt;br /&gt;                &amp;lt;title&amp;gt;Example&amp;lt;/title&amp;gt;&lt;br /&gt;            &amp;lt;/head&amp;gt;&lt;br /&gt;            &amp;lt;body&amp;gt;&lt;br /&gt;            &amp;lt;/body&amp;gt;&lt;br /&gt;        &amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;        html.&amp;lt;body&amp;gt;(0).Add(GetParagraphs())&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        html.Save(Console.Out, SaveOptions.OmitDuplicateNamespaces)&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;Function&lt;/span&gt; GetParagraphs() &lt;span style="color:blue;"&gt;As&lt;/span&gt; IEnumerable(Of XElement)&lt;br /&gt;        &lt;span style="color:blue;"&gt;Dim&lt;/span&gt; ps() &lt;span style="color:blue;"&gt;As&lt;/span&gt; &lt;span style="color:blue;"&gt;String&lt;/span&gt; = {&lt;span style="color:#a31515;"&gt;&amp;quot;Paragraph 1.&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;Paragraph 2.&amp;quot;&lt;/span&gt;}&lt;br /&gt;        &lt;span style="color:blue;"&gt;Return&lt;/span&gt; (From p &lt;span style="color:blue;"&gt;In&lt;/span&gt; ps &lt;span style="color:blue;"&gt;Select&lt;/span&gt; &amp;lt;p&amp;gt;&amp;lt;%= p %&amp;gt;&amp;lt;/p&amp;gt;)&lt;br /&gt;    &lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Function&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;End&lt;/span&gt; &lt;span style="color:blue;"&gt;Module&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;
Now the output is fine:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;html&lt;/span&gt; &lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://www.w3.org/1999/xhtml&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;head&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;title&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Example&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;title&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;head&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;body&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Paragraph 1.&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Paragraph 2.&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;body&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;html&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;Have you ever wondered why an XDocument or XElement in .NET 3.5 could be saved to a TextWriter or a file or an XmlWriter but not directly to a Stream? In .NET 3.5 you need to construct an XmlWriter or TextWriter over a Stream but now in .NET 4.0 you can save directly to a Stream: &lt;a href="http://msdn.microsoft.com/en-us/library/cc838476(VS.100).aspx"&gt;XDocument.Save(Stream)&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/cc838604(VS.100).aspx"&gt;XElement.Save(Stream)&lt;/a&gt;. No functionality gain but a convenient addition, for instance when you want to send the serialization of an XDocument or XElement to the request stream of an HttpWebRequest. There are also corresponding Load methods taking a Stream as the input, &lt;a href="http://msdn.microsoft.com/en-us/library/cc838349(VS.100).aspx"&gt;XDocument.Load(Stream)&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/library/cc838544(VS.100).aspx"&gt;XElement.Load(Stream)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;There is also a new &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.linq.readeroptions(VS.100).aspx"&gt;enumeration ReaderOptions&lt;/a&gt; in System.Xml.Linq but so far I have not found any method or property using that enumeration.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;XmlReaderSettings has a new property &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.xmlreadersettings.dtdprocessing(VS.100).aspx"&gt;DtdProcessing&lt;/a&gt; that replaces the now obsolete &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.xmlreadersettings.prohibitdtd(VS.100).aspx"&gt;ProhibitDtd&lt;/a&gt; property. With the boolean property ProhibitDtd you could choose to either allow DTD parsing/processing or to prohibit it. With the new DtdProcessing property you have now three choices, prohibit, parse, or ignore. Ignore could give you performance benefits over parse. for instance the following parses the W3C home page twice, once ignoring the DTD, once parsing/processing it:&lt;/p&gt;
&lt;pre&gt;            Stopwatch watch = &lt;span style="color:blue;"&gt;new&lt;/span&gt; Stopwatch();&lt;br /&gt;            XmlReaderSettings settings = &lt;span style="color:blue;"&gt;new&lt;/span&gt; XmlReaderSettings();&lt;br /&gt;            settings.DtdProcessing = DtdProcessing.Ignore;&lt;br /&gt;            watch.Start();&lt;br /&gt;            &lt;span style="color:blue;"&gt;using&lt;/span&gt; (XmlReader reader = XmlReader.Create(&lt;span style="color:#a31515;"&gt;@&amp;quot;http://www.w3.org/&amp;quot;&lt;/span&gt;, settings))&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color:blue;"&gt;while&lt;/span&gt; (reader.Read())&lt;br /&gt;                {&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            watch.Stop();&lt;br /&gt;            Console.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;DtdProcessing.Ignore: Elapsed time: {0}&amp;quot;&lt;/span&gt;, watch.Elapsed);&lt;br /&gt;&lt;br /&gt;            settings.DtdProcessing = DtdProcessing.Parse;&lt;br /&gt;            watch.Start();&lt;br /&gt;            &lt;span style="color:blue;"&gt;using&lt;/span&gt; (XmlReader reader = XmlReader.Create(&lt;span style="color:#a31515;"&gt;@&amp;quot;http://www.w3.org/&amp;quot;&lt;/span&gt;, settings))&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color:blue;"&gt;while&lt;/span&gt; (reader.Read())&lt;br /&gt;                {&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            watch.Stop();&lt;br /&gt;            Console.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;DtdProcessing.Parse: Elapsed time: {0}&amp;quot;&lt;/span&gt;, watch.Elapsed);&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The output for me here is&lt;/p&gt;
&lt;p&gt;DtdProcessing.Ignore: Elapsed time: 00:00:01.5245222&lt;br /&gt;DtdProcessing.Parse: Elapsed time: 00:00:09.1677892&lt;/p&gt;
&lt;p&gt;so ignoring the DTD is about nine times faster for that sample document. On the other hand if the DTD defines any entities that are then referenced in the XML document ignoring the DTD would give you an exception:&lt;/p&gt;
&lt;pre&gt;            XmlReaderSettings settings = &lt;span style="color:blue;"&gt;new&lt;/span&gt; XmlReaderSettings();&lt;br /&gt;            settings.DtdProcessing = DtdProcessing.Ignore;&lt;br /&gt;&lt;br /&gt;            &lt;span style="color:blue;"&gt;string&lt;/span&gt; xhtml = &lt;span style="color:#a31515;"&gt;@&amp;quot;&amp;lt;!DOCTYPE html &lt;br /&gt;     PUBLIC &amp;quot;&amp;quot;-//W3C//DTD XHTML 1.0 Strict//EN&amp;quot;&amp;quot;&lt;br /&gt;     &amp;quot;&amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;html xml:lang=&amp;quot;&amp;quot;en&amp;quot;&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;Example&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;Price is: 100 &amp;amp;euro;&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;            &lt;span style="color:blue;"&gt;using&lt;/span&gt; (XmlReader reader = XmlReader.Create(&lt;span style="color:blue;"&gt;new&lt;/span&gt; StringReader(xhtml), settings))&lt;br /&gt;            {&lt;br /&gt;                &lt;span style="color:blue;"&gt;while&lt;/span&gt; (reader.Read()) { }&lt;br /&gt;            }&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;throws the exception &amp;quot;Reference to undeclared entity &amp;#39;euro&amp;#39;&amp;quot;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;That&amp;#39;s all I have found so far, I will edit this post when I find more.&lt;/p&gt;
&lt;p&gt;[edit 2009-05-26] I have now found a page &amp;quot;&lt;a href="http://msdn.microsoft.com/en-us/library/1k76xshy(VS.100).aspx"&gt;What&amp;#39;s new in System.Xml&lt;/a&gt;&amp;quot; in the .NET framework 4 Beta 1 documentation. Oddly enough it lists LINQ to XML and the XSLT compiler as new features although both were introduced in .NET 3.5. It also mentions new methods in the &lt;a href="http://msdn.microsoft.com/en-us/library/system.xml.xmlconvert(VS.100).aspx"&gt;XmlConvert&lt;/a&gt; class.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1693044" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/Visual+Studio+2010/default.aspx">Visual Studio 2010</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/System.Xml/default.aspx">System.Xml</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/.NET+4.0/default.aspx">.NET 4.0</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/LINQ+to+XML/default.aspx">LINQ to XML</category></item><item><title>Creating XML with namespaces with JavaScript and MSXML</title><link>http://msmvps.com/blogs/martin_honnen/archive/2009/04/15/creating-xml-with-namespaces-with-javascript-and-msxml.aspx</link><pubDate>Wed, 15 Apr 2009 04:17:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1687764</guid><dc:creator>Martin Honnen</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/martin_honnen/rsscomments.aspx?PostID=1687764</wfw:commentRss><comments>http://msmvps.com/blogs/martin_honnen/archive/2009/04/15/creating-xml-with-namespaces-with-javascript-and-msxml.aspx#comments</comments><description>&lt;p&gt;In &lt;a href="http://msmvps.com/blogs/martin_honnen/archive/2009/04/13/creating-xml-with-namespaces-with-javascript-and-the-w3c-dom.aspx"&gt;my previous post&lt;/a&gt; I showed how to use the W3C DOM API to create XML with namespaces, using namespace aware methods like createElementNS or setAttributeNS of the W3C DOM Level 2 and 3 Core API. While &lt;a href="http://msdn.microsoft.com/en-us/library/ms763742(VS.85).aspx"&gt;MSXML&lt;/a&gt; (all versions including the latest, MSXML 6) implements the W3C DOM Level 1 Core API it does not implement any of the methods used in the previous post, like createElementNS or setAttributeNS. Instead it has a single &lt;a href="http://msdn.microsoft.com/en-us/library/ms757901(VS.85).aspx"&gt;method createNode&lt;/a&gt; that takes as its first argument the node type, as its second argument the qualified name and as its third argument the namespace you want to create a node in. This post shows how to use that method to create XML with namespaces with MSXML and JavaScript. The examples use MSXML 3 but later versions of MSXML (e.g. 4, 5, 6) expose exactly the same API.&lt;/p&gt;
&lt;p&gt;Let&amp;#39;s assume you want to create the following XML document with JavaScript and the MSXML DOM API:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt; &lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://example.com/ns1&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;foobar&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The key to doing that properly is to undestand the following: in the
XML markup there is an XML default namespace declaration attribute
xmlns=&amp;quot;http://example.com/ns1&amp;quot; on the &amp;quot;root&amp;quot; element that is in scope
for the &amp;quot;root&amp;quot; element and all its descendant elements (e.g. the &amp;quot;foo&amp;quot;
and the &amp;quot;bar&amp;quot; element) meaning all three elements, the &amp;quot;root&amp;quot; element,
the &amp;quot;foo&amp;quot; element and the &amp;quot;bar&amp;quot; element are in that namespace
http://example.com/ns1. To create that XML document programmatically
you have to create all three elements in that namespace. Thus to create those three elements, you need to call createNode three times, each time passing in the node type (1 for element node), the element name (e.g. &amp;#39;root&amp;#39;) and the namespace (e.g. &amp;#39;http://example.com/ns1&amp;#39;):&lt;/p&gt;
&lt;pre&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; doc = &lt;span style="color:blue;"&gt;new&lt;/span&gt; ActiveXObject(&lt;span style="color:#a31515;"&gt;&amp;#39;Msxml2.DOMDocument.3.0&amp;#39;&lt;/span&gt;);&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; ns1 = &lt;span style="color:#a31515;"&gt;&amp;#39;http://example.com/ns1&amp;#39;&lt;/span&gt;;&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; root = doc.createNode(1, &lt;span style="color:#a31515;"&gt;&amp;#39;root&amp;#39;&lt;/span&gt;, ns1);&lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; foo = doc.createNode(1, &lt;span style="color:#a31515;"&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;, ns1);&lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; bar = doc.createNode(1, &lt;span style="color:#a31515;"&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;, ns1);&lt;br /&gt;    bar.appendChild(doc.createTextNode(&lt;span style="color:#a31515;"&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;));&lt;br /&gt;    foo.appendChild(bar);&lt;br /&gt;    root.appendChild(foo);&lt;br /&gt;    doc.appendChild(root);&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;That creates an XML DOM document that, when serialized, looks as the above document. &lt;a href="http://home.arcor.de/martin.honnen/blog/js-examples/msxml-xml-namespaces1.html"&gt;Here is an example&lt;/a&gt;
showing that. As you can see, the DOM code did not need to create the
default namespace declaration attribute at all, nevertheless, when the document is serialized by accessing the xml property, the serialization adds it.&lt;/p&gt;
&lt;p&gt;Let&amp;#39;s look at a further example that includes elements and attributes in two namespaces:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt; &lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://example.com/ns1&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;         &lt;span style="color:red;"&gt;xmlns:xsi&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://www.w3.org/2001/XMLSchema-instance&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;         &lt;span style="color:red;"&gt;xsi:schemaLocation&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://example.com/n1 schema.xsd&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;     &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;foobar&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;[Note: for better reading I have inserted whitespace in the XML
markup but the code I will show will focus on creating the elements and
attributes only, not the whitespace.] In the above XML sample we now
have two additional attributes, one namespace declaration attribute
xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; and one attribute
in that namespace, the xsi:schemaLocation attribute. Again we do not
have to create any namespace declaration attributes at all, it suffices
to use the previous code, add a call to createNode and pass in
2 as the node type for attribute, the qualified name of the attribute (e.g. &amp;#39;xsi:schemaLocation&amp;#39;) and the namespace (e.g. &amp;#39;http://www.w3.org/2001/XMLSchema-instance&amp;#39;) to create that attribute and use setAttributeNode to add the attribute to the &amp;#39;root&amp;#39; element:&lt;/p&gt;
&lt;pre&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; doc = &lt;span style="color:blue;"&gt;new&lt;/span&gt; ActiveXObject(&lt;span style="color:#a31515;"&gt;&amp;#39;Msxml2.DOMDocument.3.0&amp;#39;&lt;/span&gt;);&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; ns1 = &lt;span style="color:#a31515;"&gt;&amp;#39;http://example.com/ns1&amp;#39;&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; xsi = &lt;span style="color:#a31515;"&gt;&amp;#39;http://www.w3.org/2001/XMLSchema-instance&amp;#39;&lt;/span&gt;;&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; root = doc.createNode(1, &lt;span style="color:#a31515;"&gt;&amp;#39;root&amp;#39;&lt;/span&gt;, ns1);&lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; schemaLocation = doc.createNode(2, &lt;span style="color:#a31515;"&gt;&amp;#39;xsi:schemaLocation&amp;#39;&lt;/span&gt;, xsi);&lt;br /&gt;    schemaLocation.nodeValue = &lt;span style="color:#a31515;"&gt;&amp;#39;http://example.com/n1 schema.xsd&amp;#39;&lt;/span&gt;;&lt;br /&gt;    root.setAttributeNode(schemaLocation);&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; foo = doc.createNode(1, &lt;span style="color:#a31515;"&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;, ns1);&lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; bar = doc.createNode(1, &lt;span style="color:#a31515;"&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;, ns1);&lt;br /&gt;    bar.appendChild(doc.createTextNode(&lt;span style="color:#a31515;"&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;));&lt;br /&gt;    foo.appendChild(bar);&lt;br /&gt;    root.appendChild(foo);&lt;br /&gt;    doc.appendChild(root);&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://home.arcor.de/martin.honnen/blog/js-examples/msxml-xml-namespaces2.html"&gt;Here is an example&lt;/a&gt;
showing the result. Again, serialization (i.e. accessing the the xml property) creates all necessary
namespace declaration attributes, as long as elements and attributes
have been created in the namespaces they belong to. The only reason to
create a namespace declaration attribute explicitly is to enforce its
output on an element where the namespace is not used. Let&amp;#39;s look at a
further example:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;svg&lt;/span&gt; &lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://www.w3.org/2000/svg&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:red;"&gt;xmlns:xlink&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://www.w3.org/1999/xlink&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;script&lt;/span&gt; &lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;text/ecmascript&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;xlink:href&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;foo.js&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;svg&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;In that XML document the XLink namespace
http://www.w3.org/1999/xlink is defined on the root element, the &amp;#39;svg&amp;#39;
element, although the namespace is only used on the &amp;#39;script&amp;#39; child
element&amp;#39;s attribute xlink:href. This time, if we want to ensure the
namespace declaration attribute appears on the &amp;#39;svg&amp;#39; element, we have
to explicitly set it on that element (and need to know that namespace
declaration attributes are per definition in the namespace
http://www.w3.org/2000/xmlns/):&lt;/p&gt;
&lt;pre&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; doc = &lt;span style="color:blue;"&gt;new&lt;/span&gt; ActiveXObject(&lt;span style="color:#a31515;"&gt;&amp;#39;Msxml2.DOMDocument.3.0&amp;#39;&lt;/span&gt;);&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; svgNs = &lt;span style="color:#a31515;"&gt;&amp;#39;http://www.w3.org/2000/svg&amp;#39;&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; xlinkNs = &lt;span style="color:#a31515;"&gt;&amp;#39;http://www.w3.org/1999/xlink&amp;#39;&lt;/span&gt;;&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; root = doc.createNode(1, &lt;span style="color:#a31515;"&gt;&amp;#39;svg&amp;#39;&lt;/span&gt;, svgNs);&lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; xlink = doc.createNode(2, &lt;span style="color:#a31515;"&gt;&amp;#39;xmlns:xlink&amp;#39;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;#39;http://www.w3.org/2000/xmlns/&amp;#39;&lt;/span&gt;);&lt;br /&gt;    xlink.nodeValue = xlinkNs;&lt;br /&gt;    root.setAttributeNode(xlink);&lt;br /&gt;        &lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; script = doc.createNode(1, &lt;span style="color:#a31515;"&gt;&amp;#39;script&amp;#39;&lt;/span&gt;, svgNs);&lt;br /&gt;    script.setAttribute(&lt;span style="color:#a31515;"&gt;&amp;#39;type&amp;#39;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;#39;text/ecmascript&amp;#39;&lt;/span&gt;);&lt;br /&gt;    &lt;span style="color:blue;"&gt;var&lt;/span&gt; href = doc.createNode(2, &lt;span style="color:#a31515;"&gt;&amp;#39;xlink:href&amp;#39;&lt;/span&gt;, xlinkNs);&lt;br /&gt;    href.nodeValue = &lt;span style="color:#a31515;"&gt;&amp;#39;foo.js&amp;#39;&lt;/span&gt;;&lt;br /&gt;    script.setAttributeNode(href);&lt;br /&gt;    &lt;br /&gt;    root.appendChild(script);&lt;br /&gt;    doc.appendChild(root);&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://home.arcor.de/martin.honnen/blog/js-examples/msxml-xml-namespaces3.html"&gt;Here is an example&lt;/a&gt; showing the result. If we did not set the namespace declaration
attribute on the &amp;#39;svg&amp;#39; element then the resulting serialized document
would nevertheless be namespace well-formed XML, only serialization
would add the namespace declaration on the &amp;#39;script&amp;#39; element.&lt;/p&gt;
&lt;p&gt;So keep two things in mind when creating XML with namespaces
programmatically with the MSXML DOM API: you need to create each element
and attribute in the namespace it belongs to, passing in the node type, the qualified name and the namespace
URI to the createNode method. And you do not
need to create namespace declaration attribute explicitly, unless you
want to enforce its appearance on an element where the namespace is not
used (like the root element of your document).&lt;/p&gt;
&lt;p&gt;The first rule is also of importance when you want to add elements
or attributes to an already loaded document. Assuming we have loaded
the following document&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt; &lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://example.com/ns1&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;and want to add a &amp;#39;bar&amp;#39; element in the same namespace as the other
elements then often people assume they can create a &amp;#39;bar&amp;#39; element with
createElement(&amp;#39;bar&amp;#39;) and add it to the root element and that it then
takes on the namespace of the root element. That is not the case
however, createElement(&amp;#39;bar&amp;#39;) creates a &amp;#39;bar&amp;#39; element in no namespace
and when you insert that as a child of the above &amp;#39;root&amp;#39; element and
serialize the serialization will add &amp;lt;bar xmlns=&amp;quot;&amp;quot;/&amp;gt; to ensure the
created element is serialized in no namespace. So to properly add a
&amp;#39;bar&amp;#39; element in the same namespace as the &amp;#39;root&amp;#39; element you again
need to use createNode and pass in the namespace URI:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; bar = doc.createNode(1, &lt;span style="color:#a31515;"&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;, doc.documentElement.namespaceURI);&lt;br /&gt;doc.documentElement.appendChild(bar);&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1687764" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/MSXML/default.aspx">MSXML</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/DOM/default.aspx">DOM</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/XML/default.aspx">XML</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/namespaces/default.aspx">namespaces</category></item><item><title>Creating XML with namespaces with JavaScript and the W3C DOM</title><link>http://msmvps.com/blogs/martin_honnen/archive/2009/04/13/creating-xml-with-namespaces-with-javascript-and-the-w3c-dom.aspx</link><pubDate>Mon, 13 Apr 2009 08:37:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1687390</guid><dc:creator>Martin Honnen</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/martin_honnen/rsscomments.aspx?PostID=1687390</wfw:commentRss><comments>http://msmvps.com/blogs/martin_honnen/archive/2009/04/13/creating-xml-with-namespaces-with-javascript-and-the-w3c-dom.aspx#comments</comments><description>&lt;p&gt;Let&amp;#39;s assume you want to create the following XML document with JavaScript and the &lt;a href="http://www.w3.org/TR/DOM-Level-2-Core/"&gt;W3C DOM API&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt; &lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://example.com/ns1&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;foobar&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;The key to doing that properly is to undestand the following: in the XML markup there is an XML default namespace declaration attribute xmlns=&amp;quot;http://example.com/ns1&amp;quot; on the &amp;quot;root&amp;quot; element that is in scope for the &amp;quot;root&amp;quot; element and all its descendant elements (e.g. the &amp;quot;foo&amp;quot; and the &amp;quot;bar&amp;quot; element) meaning all three elements, the &amp;quot;root&amp;quot; element, the &amp;quot;foo&amp;quot; element and the &amp;quot;bar&amp;quot; element are in that namespace http://example.com/ns1. To create that XML document programmatically you have to create all three elements in that namespace. Thus to create the &amp;quot;root&amp;quot; element you use the createDocument method and pass in namespace and name and to create the descendant elements you use the method createElementNS method and each time pass in the namespace and the name:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; ns1 = &lt;span style="color:#a31515;"&gt;&amp;#39;http://example.com/ns1&amp;#39;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; doc = document.implementation.createDocument(ns1, &lt;span style="color:#a31515;"&gt;&amp;#39;root&amp;#39;&lt;/span&gt;, &lt;span style="color:blue;"&gt;null&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; foo = doc.createElementNS(ns1, &lt;span style="color:#a31515;"&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; bar = doc.createElementNS(ns1, &lt;span style="color:#a31515;"&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;);&lt;br /&gt;bar.appendChild(document.createTextNode(&lt;span style="color:#a31515;"&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;));&lt;br /&gt;foo.appendChild(bar);&lt;br /&gt;doc.documentElement.appendChild(foo);&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;That creates an XML DOM document that, when serialized, looks as the above document. &lt;a href="http://home.arcor.de/martin.honnen/blog/js-examples/w3cdom-xml-namespaces1.html"&gt;Here is an example&lt;/a&gt; showing that. As you can see, the DOM code did not need to create the default namespace declaration attribute at all, nevertheless, the serializer, when serializing the DOM tree, adds it.&lt;/p&gt;
&lt;p&gt;Let&amp;#39;s look at a further example that includes elements and attributes in two namespaces:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt; &lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://example.com/ns1&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;         &lt;span style="color:red;"&gt;xmlns:xsi&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://www.w3.org/2001/XMLSchema-instance&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;         &lt;span style="color:red;"&gt;xsi:schemaLocation&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://example.com/n1 schema.xsd&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;   &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;     &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;foobar&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;bar&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;[Note: for better reading I have inserted whitespace in the XML markup but the code I will show will focus on creating the elements and attributes only, not the whitespace.] In the above XML sample we now have two additional attributes, one namespace declaration attribute xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; and one attribute in that namespace, the xsi:schemaLocation attribute. Again we do not have to create any namespace declaration attributes at all, it suffices to use the previous code and add a call to setAttributeNS and pass in the namespace and the qualified name and the value to create the xsi:schemaLocation attribute:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; ns1 = &lt;span style="color:#a31515;"&gt;&amp;#39;http://example.com/ns1&amp;#39;&lt;/span&gt;;&lt;br /&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; xsi = &lt;span style="color:#a31515;"&gt;&amp;#39;http://www.w3.org/2001/XMLSchema-instance&amp;#39;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; doc = document.implementation.createDocument(ns1, &lt;span style="color:#a31515;"&gt;&amp;#39;root&amp;#39;&lt;/span&gt;, &lt;span style="color:blue;"&gt;null&lt;/span&gt;);&lt;br /&gt;doc.documentElement.setAttributeNS(xsi, &lt;span style="color:#a31515;"&gt;&amp;#39;xsi:schemaLocation&amp;#39;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;#39;http://example.com/n1 schema.xsd&amp;#39;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; foo = doc.createElementNS(ns1, &lt;span style="color:#a31515;"&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;);&lt;br /&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; bar = doc.createElementNS(ns1, &lt;span style="color:#a31515;"&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;);&lt;br /&gt;bar.appendChild(document.createTextNode(&lt;span style="color:#a31515;"&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;));&lt;br /&gt;foo.appendChild(bar);&lt;br /&gt;doc.documentElement.appendChild(foo);&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://home.arcor.de/martin.honnen/blog/js-examples/w3cdom-xml-namespaces2.html"&gt;Here is an example&lt;/a&gt; showing the result. Again, the serializer creates all necessary namespace declaration attributes, as long as elements and attributes have been created in the namespaces they belong to. The only reason to create a namespace declaration attribute explicitly is to enforce its output on an element where the namespace is not used. Let&amp;#39;s look at a further example:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;svg&lt;/span&gt; &lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://www.w3.org/2000/svg&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:red;"&gt;xmlns:xlink&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://www.w3.org/1999/xlink&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;script&lt;/span&gt; &lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;text/ecmascript&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;xlink:href&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;foo.js&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;svg&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;In that XML document the XLink namespace http://www.w3.org/1999/xlink is defined on the root element, the &amp;#39;svg&amp;#39; element, although the namespace is only used on the &amp;#39;script&amp;#39; child element&amp;#39;s attribute xlink:href. This time, if we want to ensure the namespace declaration attribute appears on the &amp;#39;svg&amp;#39; element, we have to explicitly set it on that element (and need to know that namespace declaration attributes are per definition in the namespace http://www.w3.org/2000/xmlns/):&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; svgNs = &lt;span style="color:#a31515;"&gt;&amp;#39;http://www.w3.org/2000/svg&amp;#39;&lt;/span&gt;;&lt;br /&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; xlinkNs = &lt;span style="color:#a31515;"&gt;&amp;#39;http://www.w3.org/1999/xlink&amp;#39;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; doc = document.implementation.createDocument(svgNs, &lt;span style="color:#a31515;"&gt;&amp;#39;svg&amp;#39;&lt;/span&gt;, &lt;span style="color:blue;"&gt;null&lt;/span&gt;);&lt;br /&gt;doc.documentElement.setAttributeNS(&lt;span style="color:#a31515;"&gt;&amp;#39;http://www.w3.org/2000/xmlns/&amp;#39;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;#39;xmlns:xlink&amp;#39;&lt;/span&gt;, xlinkNs);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; script = doc.createElementNS(svgNs, &lt;span style="color:#a31515;"&gt;&amp;#39;script&amp;#39;&lt;/span&gt;);&lt;br /&gt;script.setAttributeNS(&lt;span style="color:blue;"&gt;null&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;#39;type&amp;#39;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;#39;text/ecmascript&amp;#39;&lt;/span&gt;);&lt;br /&gt;script.setAttributeNS(xlinkNs, &lt;span style="color:#a31515;"&gt;&amp;#39;xlink:href&amp;#39;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;#39;foo.js&amp;#39;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;doc.documentElement.appendChild(script);&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://home.arcor.de/martin.honnen/blog/js-examples/w3cdom-xml-namespaces3.html"&gt;Here is an example&lt;/a&gt; showing the result. If we did not set the namespace declaration attribute on the &amp;#39;svg&amp;#39; element then the resulting serialized document would nevertheless be namespace well-formed XML, only the serializer would add the namespace declaration on the &amp;#39;script&amp;#39; element.&lt;/p&gt;
&lt;p&gt;So keep two things in mind when creating XML with namespaces programmatically with the W3C DOM API: you need to create each element and attribute in the namespace it belongs to, passing in the namespace URI to methods like createElementNS or setAttributeNS. And you do not need to create namespace declaration attribute explicitly, unless you want to enforce its appearance on an element where the namespace is not used (like the root element of your document).&lt;/p&gt;
&lt;p&gt;The first rule is also of importance when you want to add elements or attributes to an already loaded document. Assuming we have loaded the following document&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt; &lt;span style="color:red;"&gt;xmlns&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;http://example.com/ns1&lt;/span&gt;&lt;span style="color:black;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#a31515;"&gt;foo&lt;/span&gt;&lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#a31515;"&gt;root&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;
&lt;p&gt;and want to add a &amp;#39;bar&amp;#39; element in the same namespace as the other elements then often people assume they can create a &amp;#39;bar&amp;#39; element with createElement(&amp;#39;bar&amp;#39;) and add it to the root element and that it then takes on the namespace of the root element. That is not the case however, createElement(&amp;#39;bar&amp;#39;) creates a &amp;#39;bar&amp;#39; element in no namespace and when you insert that as a child of the above &amp;#39;root&amp;#39; element and serialize the serializer will add &amp;lt;bar xmlns=&amp;quot;&amp;quot;/&amp;gt; to ensure the created element is serialized in no namespace. So to properly add a &amp;#39;bar&amp;#39; element in the same namespace as the &amp;#39;root&amp;#39; element you again need to use createElementNS and pass in the namespace URI:&lt;/p&gt;
&lt;pre&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; bar = doc.createElementNS(doc.documentElement.namespaceURI, &lt;span style="color:#a31515;"&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;);&lt;br /&gt;doc.documentElement.appendChild(bar);&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1687390" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/XML/default.aspx">XML</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/W3C+DOM/default.aspx">W3C DOM</category><category domain="http://msmvps.com/blogs/martin_honnen/archive/tags/namespaces/default.aspx">namespaces</category></item></channel></rss>