0

I am constructing some XML using Linq to object and have managed to get what I want using code similar to the following example. I can't help feeling that it could be better though. What really bothers me is the "illustrations" node where I have to join the group back to the original data.

You can see what I'm trying to do by running the query (I've used Linqpad). There's a list of pages, some which have illustrations. I want to list all pages with the illustrations if there are any.

Any comments please..?

var illustrations = new []
{
    new {page = 1, illustration= "a"}, 
    new {page = 2, illustration = "b"}, 
    new {page = 1, illustration = "c"}
};
var pages = new []
{
    new {page = 1, pageName = "w"}, 
    new {page = 2, pageName = "x"}, 
    new {page = 3, pageName = "y"}, 
    new {page = 4, pageName = "z"}
};


var x1 = new XElement("contents",
    from page in pages join illustration in illustrations on page.page equals illustration.page
    into pagesIllustrations from pr in pagesIllustrations.DefaultIfEmpty()  //Left outer join
    group page by page.page into g
    select new XElement("content",
        new XAttribute("contentPageName", g.First().pageName),
        new XElement("pages", 
            from o1 in g.Distinct()
            select new XElement("page",
                new XAttribute("PageNumber", o1.page),
                new XAttribute("PageName", o1.pageName))),
        new XElement("illustrations", 
            from o2 in g.Distinct() join i in illustrations on o2.page equals i.page
            select new XElement("illustration", 
                new XAttribute("PageNumber", i.page), 
                new XAttribute("IllustrationName", i.illustration)))));

x1.Dump();

Here's the xml I'm producing. It is exactly as I want it to be, I just can't help feeling I'm not doing it the best way.

<contents>
  <content contentFileName="w">
    <pages>
      <page PageNumber="1" PageName="w" />
    </pages>
    <resources>
      <resource PageNumber="1" ResourceName="a" />
      <resource PageNumber="1" ResourceName="c" />
    </resources>
  </content>
  <content contentFileName="x">
    <pages>
      <page PageNumber="2" PageName="x" />
    </pages>
    <resources>
      <resource PageNumber="2" ResourceName="b" />
    </resources>
  </content>
  <content contentFileName="y">
    <pages>
      <page PageNumber="3" PageName="y" />
    </pages>
    <resources />
  </content>
  <content contentFileName="z">
    <pages>
      <page PageNumber="4" PageName="z" />
    </pages>
    <resources />
  </content>
</contents>
ekad
  • 14,436
  • 26
  • 44
  • 46
David Hyde
  • 902
  • 9
  • 18
  • 1
    What worries me more is that you're not using `pr` anywhere... It also doesn't help that you haven't shown the XML you're trying to generate. – Jon Skeet Apr 09 '13 at 19:48
  • I put pr in to get the left outer join as not all pages have resources. I've added the xml that I'm producing. – David Hyde Apr 10 '13 at 08:19

0 Answers0