Simon Woods
Simon Woods

Reputation: 2241

Insert XElements using LINQ Select?

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

Answers (1)

Eamon Nerbonne
Eamon Nerbonne

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 XML
  • xml...<elemname> selects descendants of xml called elemname
  • 'elem.@attrname` gets the value of an attribute

It's almost XQuery ;-).

Upvotes: 2

Related Questions