views:

40

answers:

1

I have this hierarchy of XML

  <Chapters>
   <Chapter @num="">
    <Section @letter="">
     <Heading @num="" />
    </Section>
   </Chapter>
  </Chapters>

I need to do a sort so that all chapters are sequenced in ascending order, each section within that chapter is sequenced in ascending order, and each heading in that section is sorted...

Doing the following yields the Chapters sorted properly, but obivously the child data isn't sorted:

Dim chapsorted = From c In root.Elements
                 Order By c.@num Ascending
                 Select c




From there I'm lost. I tried this crazy thing to get the full results I want, but that didn't do me any good either:

Dim chapsorted = From c In root.Elements
             Order By c.@num Ascending
             Select (From sec In c.Elements Order By sec.@letter Where sec.Parent Is c Select
                    (From hed In sec.Elements Order By hed.@num Where hed.Parent Is sec)))

That did me no good either.

There has got to be a simple way of doing this.... :-) Help will be greatly appreciate, I've been spinning my wheels for hours.

+1  A: 

I think you're on the right track with your first query. Construct an XElement out of the resulting list of sorted nodes by copying the name and attributes from the original XElement, and then nest that structure:

Dim chapsorted = New XElement(root.Name, _
    root.Attributes, _
    From c In root.Elements _
    Order By c.@num Ascending _
    Select New XElement(c.Name, _
        c.Attributes, _
        From s In c.Elements _
        Order By s.@letter Ascending _
        Select New XElement(s.Name, _
            s.Attributes, _
            From h In s.Elements _
            Order By h.@num Ascending _
            Select h)))

If you were sorting by the same attribute at every level, you could do a recursive solution like this:

Private Function SortChildElements(ByVal element As XElement) As XElement
    Return New XElement( _
        element.Name, _
        element.Attributes, _
        element.Nodes.Where(Function(node) Not TypeOf node Is XElement), _
        From child In element.Elements _
        Order By child.@num Ascending _
        Select SortChildElements(child))
End Function
Quartermeister
THank you thank you! I'll try this first thing tomorrow!
Matt H.