views:

73

answers:

1

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

+2  A: 

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 ;-).

Eamon Nerbonne
Excellent ... many thx (and fast!)
Simon Woods
yes ... that - xml literals - is much nicer! Thx again
Simon Woods
xml literals.... what a neat thing C# programmers don't get to have :(
slf
@slf: It's all compile-time type-checked too, which is handy, since I've never written a VB-program in my life, merely pined for exactly that feature :-)
Eamon Nerbonne