1 #Region "Microsoft.VisualBasic::14a0f2801edc83c85c1320e092067316, Microsoft.VisualBasic.Core\Text\Xml\Linq\NodeIterator.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Module NodeIterator
35     
36     '         Function: IterateArrayNodes
37     
38     
39     ' /********************************************************************************/
40
41 #End Region
42
43 Imports System.Runtime.CompilerServices
44 Imports System.Xml
45 Imports Microsoft.VisualBasic.Language
46
47 Namespace Text.Xml.Linq
48
49     Public Module NodeIterator
50
51         ''' <summary>
52         ''' 使用<see cref="XmlDocument.Load"/>方法加载XML文档依旧是一次性的全部加载所有的文本到内存之中,第一次加载效率会比较低
53         ''' 则可以使用这个方法来加载非常大的XML文档
54         ''' </summary>
55         ''' <param name="path$"></param>
56         ''' <returns></returns>
57         <Extension> Public Iterator Function IterateArrayNodes(path$, tag$) As IEnumerable(Of String)
58             Dim buffer As New List(Of String)
59             Dim start$ = "<" & tag
60             Dim ends$ = $"</{tag}>"
61             Dim stack%
62             Dim tagOpen As Boolean = False
63             Dim lefts$
64             Dim i%
65
66             For Each line As String In path.IterateAllLines
67                 If tagOpen Then
68
69                     i = InStr(line, ends)
70
71                     If i > 0 Then
72                         ' 遇到了结束标签,则取出来
73                         If stack > 0 Then
74                             stack -= 1 ' 内部栈,还没有结束,则忽略当前的这个标签
75                         Else
76                             ' 这个是真正的结束标签
77                             lefts = Mid(line, i + ends.Length)
78                             buffer += ends
79                             tagOpen = False
80
81                             Yield buffer.JoinBy(vbLf)
82
83                             buffer *= 0
84                             buffer += lefts
85
86                             ' 这里要跳出来,否则后面buffer += line处任然会添加这个结束标签行的
87                             Continue For
88                         End If
89                     ElseIf InStr(line, start) > 0 Then
90                         stack += 1
91                     End If
92
93                     buffer += line
94                 Else
95                     ' 需要一直遍历到开始标签为止
96                     i = InStr(line, start)
97
98                     If i > 0 Then
99                         tagOpen = True
100                         buffer += Mid(line, i)
101                     End If
102                 End If
103             Next
104         End Function
105     End Module
106 End Namespace