Reputation: 2241
I have a source piece of xml into which I want to insert multiple elements which are created dependant upon certain values found in the original xml
At present I have a sub which does this for me:
<Extension()>
Public Sub AddElements(ByVal xml As XElement, ByVal elementList As IEnumerable(Of XElement))
For Each e In elementList
xml.Add(e)
Next
End Sub
And this is getting invoked in a routine as follows:
Dim myElement = New XElement("NewElements")
myElement.AddElements(
xml.Descendants("TheElements").
Where(Function(e) e.Attribute("FilterElement") IsNot Nothing).
Select(Function(e) New XElement("NewElement", New XAttribute("Text", e.Attribute("FilterElement").Value))))
Is it possible to re-write this using Linq syntax so I don't need to call out to the Sub AddElements but could do it all in-line
Many Thx
Simon
Upvotes: 2
Views: 704
Reputation: 48066
Sure:
Dim outputxml =
New XElement("NewElements",
xml.Descendants("TheElements").
Where(Function(e) e.Attribute("FilterElement") IsNot Nothing).
Select(Function(e) _
New XElement("NewElement",
New XAttribute("Text",e.Attribute("FilterElement").Value)
)
)
)
XElement
and XAttribute
have constructors which (in addition to the element or attribute name) accept an arbitrary number of objects (which themselves can be queries or other IEnumerables
). Anything you pass to the constructor is added as content.
You may also want to look into XML-literals, which make this much more readable but essentially do the same thing.
With XML Literals, it looks like this:
dim outputxml =
<NewElements><%=
From e In xml...<TheElements>
Where e.@FilterElement IsNot Nothing
Select <NewElement Text=<%= e.@FilterElement %>/>
%></NewElements>
' you can embed names and attribute values too
<%=
%>
embeds a VB expression's value in XMLxml...<elemname>
selects descendants of xml called elemnameIt's almost XQuery ;-).
Upvotes: 2