VB中的递归排序XML标记

时间:2012-08-13 22:09:01

标签: xml vb.net sorting recursion

我仍然对Visual Basic和XML有些新意,所以我不知道我是否正确地说这个。我只是触及了XSLT的表面,但是从我到目前为止看到的我不知道它是否可以做到这一点。

我试图通过Visual Basic中的标记按字母顺序递归排序XML文件。例如,对于XML文档,例如:

<catalog>
  <game>
      <title>Role-playing EXTREME Adventure</title>
      <platform>PC</platform>
      <type>Action/Adventure</type>
      <price>60.00</price>
  </game>
  <cd>
      <title>Music Notes</title>
      <artist>Susan Dylan</artist>
      <genre>Rock</genre>
      <company>Columbia</company>
      <year>1995</year>
      <price>10.95</price>
  </cd>
  <book>
      <title>Pictures of Things</title>
      <author>Bob Smith</author>
      <type>paper-back</type>
      <price>5.99</price>
  </book>
</catalog>

...变为:

<catalog>
  <book>
      <author>Bob Smith</author>
      <price>5.99</price>
      <title>Pictures of Things</title>
      <type>paper-back</type>
  </book>
  <cd>
      <artist>Susan Dylan</artist>
      <company>Columbia</company>
      <genre>Rock</genre>
      <price>10.95</price>
      <title>Music Notes</title>
      <year>1995</year>
  </cd>
  <game>
      <platform>PC</platform>
      <price>60.00</price>
      <title>Role-playing EXTREME Adventure</title>
      <type>Action/Adventure</type>
  </game>
</catalog>

此排序版本应替换XML文件的内容并保存。这将针对多个长XML文件完成。我不在我的工作电脑上,所以我无法访问我一直在摆弄的乱七八糟的Visual Basic代码。我开始认为我应该抛弃我已经做过的事情。

如果在某处得到解答,我道歉。我花了大部分时间搜索并研究这个问题。因此,如果已经有答案,我期待获得它的链接。 :)

我看到了this,但它似乎无法满足我的需求。它必须在Visual Basic中完成,而不是在命令行中完成。

我感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

这是一个可用于对XML进行排序的程序(至少需要.NET 3.0才能使用LINQ to XML和扩展方法,但这也可以使用旧式XML解析库和常规方法完成):

Imports System.Xml.Linq
Imports System.Runtime.CompilerServices

Module Module1

Sub Main()
    Dim xe As XElement = XElement.Load("test.xml")
    Console.WriteLine("----Original XML----")
    Console.WriteLine(xe)
    xe.SortRecursive()
    Console.WriteLine("----Sorted XML----")
    Console.WriteLine(xe)
End Sub

''' <summary>
''' Sorts the subelements of an XML element, and their subelements recursively.
''' </summary>
''' <param name="xe"></param>
''' <remarks></remarks>
<Extension()>
Sub SortRecursive(xe As XElement)
    xe.Sort()
    For Each subelement As XElement In xe.Elements()
        subelement.SortRecursive()
    Next
End Sub

''' <summary>
''' Sorts the subelements of an XML element.
''' </summary>
''' <param name="xe">The element whose subelements are to be sorted.</param>
<Extension()>
Sub Sort(xe As XElement)
    ' Save off the subelements into a list, and remove them from the main element
    Dim subelements As New List(Of XElement)
    For Each subelement As XElement In xe.Elements().ToArray()
        subelement.Remove()
        subelements.Add(subelement)
    Next

    ' Sort the list of subelements
    subelements.Sort(AddressOf CompareElementNames)

    ' Add the elements back and return when done
    For Each subelement As XElement In subelements
        xe.Add(subelement)
    Next
End Sub

''' <summary>
''' Compares two XML elements by their names.
''' </summary>
''' <param name="e1">The first element.</param>
''' <param name="e2">The second element.</param>
''' <returns>positive/negative/zero depending on comparison (same as string comparison)</returns>
Function CompareElementNames(e1 As XElement, e2 As XElement) As Integer
    Return String.Compare(e1.Name.ToString(), e2.Name.ToString())
End Function
End Module

答案 1 :(得分:0)

这似乎对我很好:

Dim recurse As Action(Of XElement) = Nothing
recurse = _
    Sub (x)
        For Each e in x _
                .Elements() _
                .OrderBy(Function (y) y.Name.LocalName) _
                .ToArray()
            recurse(e)
            e.Remove()
            x.Add(e)
        Next
    End Sub

我测试了这些数据:

Dim xml = _
    <catalog>
        <game>
            <title>Role-playing EXTREME Adventure</title>
            <platform>PC</platform>
            <type>Action/Adventure</type>
            <price>60.00</price>
        </game>
        <cd>
            <title>Music Notes</title>
            <artist>Susan Dylan</artist>
            <genre>Rock</genre>
            <company>Columbia</company>
            <year>1995</year>
            <price>10.95</price>
        </cd>
        <book>
            <title>Pictures of Things</title>
            <author>Bob Smith</author>
            <type>paper-back</type>
            <price>5.99</price>
        </book>
    </catalog>

致电:

recurse(xml)

得到了这个结果:

<catalog>
  <book>
    <author>Bob Smith</author>
    <price>5.99</price>
    <title>Pictures of Things</title>
    <type>paper-back</type>
  </book>
  <cd>
    <artist>Susan Dylan</artist>
    <company>Columbia</company>
    <genre>Rock</genre>
    <price>10.95</price>
    <title>Music Notes</title>
    <year>1995</year>
  </cd>
  <game>
    <platform>PC</platform>
    <price>60.00</price>
    <title>Role-playing EXTREME Adventure</title>
    <type>Action/Adventure</type>
  </game>
</catalog>