0

I am trying to print out documents in various different orders. Right now I have a collection of print objects and an XML document where each node has attributes associated with a print object in the collection. I want to sort these objects by sorting the XML document based on these attributes.

Right now I am using a series of collections that i am cycling through and adding the node into a new collection based on the sorting i need done. The problem is 3 or 4 sorts in it gets messy. I am sure there has to be a better way to sort this collection of print objects, using XML or not.

Here are some attributes that my XML has that i am sorting on:

  • # of pages
  • Zip Code listed on document
  • Name of Document

Does anyone have a better idea?

thanks,

EDIT -

my document will look something like

<xml>
<claim key="1" att1="wd" att2="de"/>
<claim key="2" att1="wd" att2="de"/>
<claim key="3" att1="wd" att2="de"/>
<claim key="4" att1="wd" att2="de"/>
</xml>

The key value is associated with a spot in the print object collection. The claim nodes may have more child nodes but i do not think that is relevant at this point. I would just like to be able to sort based on the attributes, there will be at least 3 attributes but more may be added. Also this needs to be versatile so if I need to switch the sorting order it should be somewhat easy to rearrange. Once I have the XML in the correct order I want, then i use a cycle through the XML in order putting the key into a list and then print out the Print objects by the keys in that list.

thanks,

kds6253
  • 835
  • 1
  • 12
  • 17
  • Can you post an example of the document and how you are linking the XML nodes to the print object, please? It would help a great deal. – deadlyvices Mar 19 '12 at 13:08
  • 2
    I'm going to suggest that possibly a little LINQ with some grouping and sorting will help you out, but we'd have to see what the XML looks like to give you any concrete examples. [Here's a post](http://stackoverflow.com/questions/5013710/linq-order-by-group-by-and-order-by-each-group) to give you an idea of what I'm talking about. – Cᴏʀʏ Mar 19 '12 at 13:11

1 Answers1

1

I tried this example out in LINQPad and it seems to do what you're asking.

var root = XDocument.Parse("<xml><claim>...</claim></xml>").Element("xml");

var query = from claim in root.Elements("claim")
            let key = claim.Attributes("key").First().Value
            let att1 = claim.Attributes("att1").First().Value
            let att2 = claim.Attributes("att2").First().Value
            orderby key, att1, att2
            select claim;

It finds the <claim> nodes in your XML, selects the attributes on which you'd like to sort, sorts them, and then returns an IEnumerable<XElement> collection representing the sorted <claim> nodes.

You can then use the query result to build your Print objects, or you could change the above to have it do it for you:

var query2 = from claim in root.Elements("claim")
            let key = claim.Attributes("key").First().Value
            let att1 = claim.Attributes("att1").First().Value
            let att2 = claim.Attributes("att2").First().Value
            orderby key, att1, att2
            select new Print {
                        Property1 = key, // do type conversion if needed
                        Property2 = att1,
                        Property3 = att2
                    };

I think it fits the maintainability requirements you mentioned -- you just have to change add/remove/change the attribute names in the LINQ query if you need to sort differently.

EDIT: To get the key into a list of ints, as per your comment below:

var printKeys = (from claim in query
                select Integer.Parse(claim.Attributes("key").First().Value)).ToList();
Cᴏʀʏ
  • 105,112
  • 20
  • 162
  • 194
  • This looks like it will work for what I need, My only question is, since I am somewhat new to c#, how can I loop through the IEnumerable collection so that I can put the Key value in a list of ints. I would not order by key, the key will just allow me to figure out which spot in the print obj collection to print. – kds6253 Mar 19 '12 at 13:50
  • Thanks, I am working with it now. Do you have any recommended reading on XDocument and the solutuon you used. I would like to read more into it, this solution is 100 times simpler then I originally came up with and I would like to learn where else this type of solution could be used. – kds6253 Mar 19 '12 at 13:57
  • @kds6253: Good question. LINQ is a really powerful addition to the .NET Framework -- you'll find that it's uses are endless. When I first dove into it, I experimented with the MSDN examples [here](http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b), and I also bought [this book](http://www.amazon.com/Pro-LINQ-Language-Integrated-Experts/dp/1590597893/ref=sr_1_6?ie=UTF8&qid=1332166210&sr=8-6). I believe the new `XDocument` and `XElement` classes are covered in the LINQ to XML section of that book. – Cᴏʀʏ Mar 19 '12 at 14:11
  • How can I tell if the query collection is full? My list of keys is not being filled so i am not sure if my query collection is empty or if i am not doing something right with filling the list of ints. – kds6253 Mar 19 '12 at 14:42
  • @kds6253: What do you mean by "full"? If you want to check if it has any elements, you can check `query.Any()` or `query.Count() > 0`. – Cᴏʀʏ Mar 19 '12 at 14:44