我仍然对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中完成,而不是在命令行中完成。
我感谢任何帮助。
答案 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>