Возможна ли рекурсия с XML-литералами в VB.NET?
У меня есть класс с именем Profile, который имеет несколько простых свойств, а затем он может иметь коллекцию ProfileItem, которая снова имеет некоторые простые свойства, а затем он может иметь коллекцию ProfileItem (RECURSION).
Сейчас я пытаюсь сгенерировать очень простую функцию сохранения, используя XML Literal, которые поставляются с VB.NET (3.5).
Я использую следующий код:
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>
Часть, связанная с тегом, должна стать рекурсивной, но я не знаю, поддерживается ли она каким-либо образом этим синтаксисом.
Должен ли я переписать все, избегая использования XML Literal для реализации рекурсии?
1 ответ
Рекурсия - одна из причин, по которой я люблю VB.NET XML Literals!
Чтобы выполнить рекурсию, вам нужна функция, которая принимает коллекцию ProfileItems и возвращает XElement. Затем вы можете рекурсивно вызвать эту функцию внутри вашего XML Literal.
Кроме того, чтобы рекурсия работала, GetProfileItems и GetDependencies должны иметь одинаковые имена (переименовать одно из них) и отображаться с одинаковой структурой элемента XML. Вот как может выглядеть рекурсивная функция:
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
Рекурсия закончится, когда вы доберетесь до элемента, который возвращает пустой список для функции GetDependencies. В этом случае вложенные items
элемент будет пустым: <items/>
, XML-литералы достаточно умны, чтобы объединить начало и конец items
теги, когда нет дочерних элементов.