views:

374

answers:

1

I have a class called Profile that has some simple properties and then it can have a collection of ProfileItem that again has some simple properties and then it can have a collection of ProfileItem (RECURSION).

Now I am trying to generated a very simple save function using XML Literals that come with VB.NET (3.5).

The code I am using is the following:

  Dim xdoc As XDocument = _
            <?xml version="1.0" encoding="utf-8"?>
            <profiles>
                <%= _
                    From p In _Profiles _
                    Select <profile name=<%= p.Name %>>
                               <%= _
                                   From i In p.GetProfileItems _
                                   Select <item>
                                              <name><%= i.Name %></name>
                                              <action><%= i.Action.ToString %></action>
                                              <type><%= i.Type.ToString %></type>
                                              <arguments><%= i.Arguments %></arguments>
                                              <dependencies>
                                                  <%= _
                                                      From d In i.GetDependencies _
                                                      Select <dependency>
                                                                 <name><%= d.Name %></name>
                                                             </dependency> _
                                                  %>
                                              </dependencies>
                                          </item> _
                               %>
                           </profile> _
                %>
            </profiles>

The part related to tag should become recursive, but I don't know if it is in some way supported by this syntax.

Should I rewrite all avoiding usage of XML Literal to implement recursion?

+4  A: 

Recursion is one of the reasons I love VB.NET XML Literals!

In order to do the recursion, you need a function that accepts a ProfileItems collection and returns an XElement. Then you can recursively call that function inside your XML Literal.

Also, in order for the recursion to work, GetProfileItems and GetDependencies need to have the same name (rename one of them) and display with the same Xml Element structure. Here's what the recursive function might look like:

Function GetProfileItemsElement(ByVal Items As List(Of ProfileItem) As XElement
    Return <items>
               <%= From i In Items _
                   Select <item>
                              <name><%= i.Name %></name>
                              <!-- other elements here -->
                              <%= GetProfileItemsElement(i.GetDependencies) %>
                          </item> %>
           </items>
End Function

The recursion will end when you get to an item that returns an empty list for the GetDependencies function. In that case, the nested items element will be empty: <items/>. XML Literals are smart enough to combine the start and end items tags when there aren't any child elements.

Dennis Palmer
great Dennis, your answer helped me a lot
marco.ragogna