jhfelectric jhfelectric - 6 months ago 16
Vb.net Question

Linq to xml combine values

Consider the following MediaObject class

Public Class MediaObject
Public Path as String
Public File as String
Public Sub New(_path as String, _file as String)
Path = _path
File = _file
End Sub
End Class


I have the following XML (myxml):

<records>
<media>
<path>\\first\path</path>
<file>firstfile</file>
</media>
<media>
<path>\\second\path</path>
<file>secondfile</file>
</media>
<records>


To get a list of MediaObjects I use this :

Dim mobjects As New List(Of MediaObject)
Dim x As XDocument = XDocument.Parse(myxml)

mobjects = (From m In x.<records>.<media> Select media = New MediaObject(m.<path>.Value, m.<file>.Value)).ToList()


All is fine.
But now consider this new XML (where second file is an alternate of the first one) :

<records>
<media>
<path>\\first\path</path>
<file>firstfile</file>
<path>\\second\path</path>
<file>secondfile</file>
</media>
</records>


I can easily get either of properties but not both, i.e.

Dim mobjects As New List(Of MediaObject)
Dim x As XDocument = XDocument.Parse(myxml)

'here get only the paths
Dim r = (From m In x.<records>.<media> Select media = (From t In m.<path> Select New MediaObject(t.Value, Nothing)).ToList()).ToList()

mobjects = r(0)


How would I go to create a list of MediaObjects in this context ?
(let's consider path and file values in the xml are in sequence and go 2 by 2)

Thanks!

UPDATE:
Sorry I wasn't precise enough.
Here is the real world scenario.
There can many paths and files and it's guaranteed


  • paths come before files

  • there is the same number of paths and files

  • all paths come first, then all files



Sample:

<records>
<media>
<some_tags />
<path>\\first\path</path>
<path>\\second\path</path>
<might_be_something_here />
<file>firstfile</file>
<file>secondfile</file>
<more_tags />
</media>
</records>


PS: I cannot change the XML, which comes from another system...

Answer

Assuming you're simply pairing up every nth path and file, you can do this:

Dim paths = doc...<path>
Dim files = doc...<file>
Dim query = paths.Zip(files, Function(p, f)
    New MediaObject(CType(p, String), CType(f, String))
)

You don't even have to worry about possible elements that are in between, they'll simply be ignored.