避免递归这个函数 XML 相关
Avoid recursion on this function XML related
此函数检索 XML 文档的 XPath:
''' <summary>
''' Gets all the XPath expressions of an <see cref="Xml.XmlDocument"/> document.
''' </summary>
''' <param name="Document">Indicates the <see cref="Xml.XmlDocument"/> object.</param>
''' <returns>List(Of System.String).</returns>
Public Function GetXmlXPaths(ByVal Document As Xml.XmlDocument) As List(Of String)
Dim XPathList As New List(Of String)
Dim XPath As String = String.Empty
For Each Child As Xml.XmlNode In Document.ChildNodes
If Child.NodeType = Xml.XmlNodeType.Element Then
GetXmlXPaths(Child, XPathList, XPath)
End If
Next ' child
Return XPathList
End Function
''' <summary>
''' Gets all the XPath expressions of an <see cref="Xml.XmlNode"/>.
''' </summary>
''' <param name="Node">Indicates the <see cref="Xml.XmlNode"/>.</param>
''' <param name="XPathList">Indicates a ByReffered XPath list as a <see cref="List(Of String)"/>.</param>
''' <param name="XPath">Indicates the current XPath.</param>
Private Sub GetXmlXPaths(ByVal Node As Xml.XmlNode,
ByRef XPathList As List(Of String),
Optional ByVal XPath As String = Nothing)
XPath &= "/" & Node.Name
If Not XPathList.Contains(XPath) Then
XPathList.Add(XPath)
End If
For Each Child As Xml.XmlNode In Node.ChildNodes
If Child.NodeType = Xml.XmlNodeType.Element Then
GetXmlXPaths(Child, XPathList, XPath)
End If
Next ' child
End Sub
这是一个用法示例:
Private Sub Test()
Dim xml As New Xml.XmlDocument
xml.LoadXml((<?xml version="1.0" encoding="Windows-1252"?>
<!--XML Songs Database-->
<Songs>
<Song><Name>My Song 1.mp3</Name></Song>
<Song><Name>My Song 2.ogg</Name></Song>
<Song><Name>My Song 3.wav</Name></Song>
</Songs>).ToString)
Dim xPathList As List(Of String) = GetXmlXPaths(xml)
ListBox1.Items.AddRange(xPathList.ToArray)
End Sub
我想在实现迭代器的同时改进函数以避免递归:
Public Iterator Function GetXmlXPaths(ByVal document As Xml.XmlDocument) _
As IEnumerable(Of String)
Yield ...
End Function
我该怎么做?
您可以尝试使用XmlReader 的读取功能。这将一一读取所有节点。然后它只是关于将以前的节点存储在列表中。我不知道这对更大的 xml.
效果如何
Dim xml As New Xml.XmlDocument
xml.LoadXml((<?xml version="1.0" encoding="Windows-1252"?>
<!--XML Songs Database-->
<Songs>
<Song><Name>My Song 1.mp3</Name></Song>
<Song><Name>My Song 2.ogg</Name></Song>
<Song><Name>My Song 3.wav</Name></Song>
</Songs>).ToString)
Dim xPathList As New List(Of String)
Dim reader As XmlReader = xml.CreateNavigator.ReadSubtree
Dim curNodes As New List(Of String)
Dim curPath As String
While reader.Read()
If reader.NodeType = XmlNodeType.Element Then
If curNodes.Count <= reader.Depth Then
curNodes.Add(reader.Name)
Else
curNodes(reader.Depth) = reader.Name
End If
curPath = String.Join("/", curNodes.ToArray(), 0, reader.Depth + 1)
If Not xPathList.Contains(curPath) Then
xPathList.Add(curPath)
End If
End If
End While
For Each s As String In xPathList
Console.WriteLine(s)
Next
此函数检索 XML 文档的 XPath:
''' <summary>
''' Gets all the XPath expressions of an <see cref="Xml.XmlDocument"/> document.
''' </summary>
''' <param name="Document">Indicates the <see cref="Xml.XmlDocument"/> object.</param>
''' <returns>List(Of System.String).</returns>
Public Function GetXmlXPaths(ByVal Document As Xml.XmlDocument) As List(Of String)
Dim XPathList As New List(Of String)
Dim XPath As String = String.Empty
For Each Child As Xml.XmlNode In Document.ChildNodes
If Child.NodeType = Xml.XmlNodeType.Element Then
GetXmlXPaths(Child, XPathList, XPath)
End If
Next ' child
Return XPathList
End Function
''' <summary>
''' Gets all the XPath expressions of an <see cref="Xml.XmlNode"/>.
''' </summary>
''' <param name="Node">Indicates the <see cref="Xml.XmlNode"/>.</param>
''' <param name="XPathList">Indicates a ByReffered XPath list as a <see cref="List(Of String)"/>.</param>
''' <param name="XPath">Indicates the current XPath.</param>
Private Sub GetXmlXPaths(ByVal Node As Xml.XmlNode,
ByRef XPathList As List(Of String),
Optional ByVal XPath As String = Nothing)
XPath &= "/" & Node.Name
If Not XPathList.Contains(XPath) Then
XPathList.Add(XPath)
End If
For Each Child As Xml.XmlNode In Node.ChildNodes
If Child.NodeType = Xml.XmlNodeType.Element Then
GetXmlXPaths(Child, XPathList, XPath)
End If
Next ' child
End Sub
这是一个用法示例:
Private Sub Test()
Dim xml As New Xml.XmlDocument
xml.LoadXml((<?xml version="1.0" encoding="Windows-1252"?>
<!--XML Songs Database-->
<Songs>
<Song><Name>My Song 1.mp3</Name></Song>
<Song><Name>My Song 2.ogg</Name></Song>
<Song><Name>My Song 3.wav</Name></Song>
</Songs>).ToString)
Dim xPathList As List(Of String) = GetXmlXPaths(xml)
ListBox1.Items.AddRange(xPathList.ToArray)
End Sub
我想在实现迭代器的同时改进函数以避免递归:
Public Iterator Function GetXmlXPaths(ByVal document As Xml.XmlDocument) _
As IEnumerable(Of String)
Yield ...
End Function
我该怎么做?
您可以尝试使用XmlReader 的读取功能。这将一一读取所有节点。然后它只是关于将以前的节点存储在列表中。我不知道这对更大的 xml.
效果如何 Dim xml As New Xml.XmlDocument
xml.LoadXml((<?xml version="1.0" encoding="Windows-1252"?>
<!--XML Songs Database-->
<Songs>
<Song><Name>My Song 1.mp3</Name></Song>
<Song><Name>My Song 2.ogg</Name></Song>
<Song><Name>My Song 3.wav</Name></Song>
</Songs>).ToString)
Dim xPathList As New List(Of String)
Dim reader As XmlReader = xml.CreateNavigator.ReadSubtree
Dim curNodes As New List(Of String)
Dim curPath As String
While reader.Read()
If reader.NodeType = XmlNodeType.Element Then
If curNodes.Count <= reader.Depth Then
curNodes.Add(reader.Name)
Else
curNodes(reader.Depth) = reader.Name
End If
curPath = String.Join("/", curNodes.ToArray(), 0, reader.Depth + 1)
If Not xPathList.Contains(curPath) Then
xPathList.Add(curPath)
End If
End If
End While
For Each s As String In xPathList
Console.WriteLine(s)
Next