xmlvb.netlinq

How to sort a collection of XElements by their XElement name


I have the following XML; I read it as a collection of XElements:

<rql:select rdf:parseType=""Resource"" xmlns:rdf=""http://www.w3.org/1999/02/22-rdf-syntax-ns#"" xmlns:rql=""http://www.ibm.com/xmlns/rdm/rql/"">
  <rdf:_22 rdf:parseType=""Resource"">
    <rql:field rdf:resource=""https://myserver.io:9443/rm/types/AD_f2cj0RV6EemaLdP_3R0zIQ"" />
    <rql:object>R1</rql:object>
  </rdf:_22>
  <rdf:_14 rdf:parseType=""Resource"">
    <rql:field rdf:resource=""https://myserver.io:9443/rm/types/AD_tEUSIXs4EeeSaIGgVG63HA"" />
    <rql:object>R1</rql:object>
  </rdf:_14>
  <rdf:_16 rdf:parseType=""Resource"">
    <rql:field rdf:resource=""https://myserver.io:9443/rm/types/AD_UOY7kF4EEe6HPajZS8U1aA"" />
    <rql:object>R1</rql:object>
  </rdf:_16>
</rql:select>

I would like to sort the collection using the element names. In this case, the element name would be the number represented by an underscore.

I have already tried to access this name, but only succeeded by looping through the individual elements. Is it possible to order the collection directly in one command?


Solution

  • I would define helper method to extract suffix to use in sorting the collection:

    Private Function GetNumericSuffix(localName As String) As Integer
        Dim parts() As String = localName.Split("_"c)
        Dim number As Integer
        If parts.Length > 1 AndAlso Integer.TryParse(parts(1), number) Then
            Return number
        Else
            Return Integer.MaxValue
        End If
    End Function
    

    And the you can use like below:

    Public Sub Main()
        Dim xml As String = "
    <rql:select rdf:parseType='Resource' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:rql='http://www.ibm.com/xmlns/rdm/rql/'>
      <rdf:_22 rdf:parseType='Resource'>
        <rql:field rdf:resource='https://myserver.io:9443/rm/types/AD_f2cj0RV6EemaLdP_3R0zIQ' />
        <rql:object>R1</rql:object>
      </rdf:_22>
      <rdf:_14 rdf:parseType='Resource'>
        <rql:field rdf:resource='https://myserver.io:9443/rm/types/AD_tEUSIXs4EeeSaIGgVG63HA' />
        <rql:object>R1</rql:object>
      </rdf:_14>
      <rdf:_16 rdf:parseType='Resource'>
        <rql:field rdf:resource='https://myserver.io:9443/rm/types/AD_UOY7kF4EEe6HPajZS8U1aA' />
        <rql:object>R1</rql:object>
      </rdf:_16>
    </rql:select>"
    
        Dim doc As XElement = XElement.Parse(xml)
    
        ' Sort child elements using a helper function to extract the numeric suffix
        Dim sortedElements As List(Of XElement) = doc.Elements() _
            .OrderBy(Function(el) GetNumericSuffix(el.Name.LocalName)) _
            .ToList()
    
        For Each el As XElement In sortedElements
            Console.WriteLine(el)
        Next
    End Sub