Skip to content

Commit 71e0109

Browse files
committed
fix children() for LazyNode
1 parent 6e17f7b commit 71e0109

File tree

1 file changed

+30
-24
lines changed

1 file changed

+30
-24
lines changed

src/XML.jl

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ module XML
33
using OrderedCollections: OrderedDict
44
using Mmap
55
using Tables
6-
using AbstractTrees: AbstractTrees
6+
using AbstractTrees: AbstractTrees, children
77

8-
export Node, NodeType
8+
export Node, NodeType, children
99

1010
#-----------------------------------------------------------------------------# escape/unescape
1111
escape_chars = ['&' => "&amp;", '"' => "&quot;", ''' => "&#39;", '<' => "&lt;", '>' => "&gt;"]
@@ -189,46 +189,51 @@ end
189189

190190
#-----------------------------------------------------------------------------# Lazy
191191
struct LazyNode
192-
tokens::Tokens
193192
data::TokenData
194193
end
195-
LazyNode(t::Tokens) = LazyNode(t, init(t))
194+
LazyNode(t::Tokens) = LazyNode(init(t))
196195
LazyNode(filename::AbstractString) = LazyNode(Tokens(filename))
197196

198-
function Base.get(o::LazyNode)
199-
iszero(o.data.pos) ? RowNode(0, DOCUMENT_NODE, nothing, nothing, nothing) : RowNode(o.data)
200-
end
197+
Base.get(o::LazyNode) = RowNode(o.data)
201198

202-
next(o::LazyNode) = LazyNode(o.tokens, next(o.data))
203-
prev(o::LazyNode) = LazyNode(o.tokens, prev(o.data))
199+
function next(o::LazyNode)
200+
x = next(o.data)
201+
isnothing(x) ? nothing : LazyNode(x)
202+
end
203+
function prev(o::LazyNode)
204+
x = prev(o.data)
205+
isnothing(x) ? nothing : LazyNode(x)
206+
end
204207

205208
function Base.show(io::IO, o::LazyNode)
206-
print(io, "Lazy: ")
209+
print(io, "LazyNode: ")
207210
show(io, get(o))
208211
end
209212
function AbstractTrees.children(o::LazyNode)
210-
i = o.i
211-
depth = iszero(i) ? 0 : o.tokens[i].depth
213+
depth = o.data.depth
212214
out = LazyNode[]
213-
for j in (i+1):length(o.tokens)
214-
tok = o.tokens[j]
215-
tok.depth == depth && break
216-
tok.depth == depth + 1 && push!(out, LazyNode(o.tokens, j))
215+
x = o
216+
while !isnothing(x)
217+
x = next(x)
218+
isnothing(x) && break
219+
x.data.tok === TOK_END_ELEMENT && continue
220+
x.data.depth == depth && break
221+
x.data.depth == depth + 1 && push!(out, x)
217222
end
218223
return out
219224
end
220225
AbstractTrees.nodevalue(o::LazyNode) = get(o)
226+
221227
function AbstractTrees.parent(o::LazyNode)
222-
iszero(i) && return nothing
223-
i = findprev(x -> x.depth < o.tokens[o.i].depth, o.tokens, o.i - 1)
224-
isnothing(i) ? LazyNode(o.tokens, 0) : LazyNode(o.tokens, i)
228+
depth = o.data.depth
229+
x = prev(o)
230+
while !isnothing(x)
231+
x.data.depth == depth - 1 && return x
232+
x = prev(x)
233+
end
234+
return nothing
225235
end
226236

227-
function lazy(t::Tokens)
228-
tokens = filter!(x -> x.tok !== TOK_END_ELEMENT, collect(t))
229-
LazyNode(tokens, 0)
230-
end
231-
lazy(filename::AbstractString) = lazy(Tokens(filename))
232237

233238
#-----------------------------------------------------------------------------# Rows
234239
struct Rows
@@ -247,6 +252,7 @@ struct RowNode
247252
end
248253
function RowNode(t::TokenData)
249254
(; tok, pos, len, depth) = t
255+
pos === 0 && return RowNode(0, DOCUMENT_NODE, nothing, nothing, nothing)
250256
data = view(t.data, pos:pos+len)
251257
@views if tok === TOK_TEXT # text
252258
return RowNode(depth, TEXT_NODE, nothing, nothing, unescape(String(data)))

0 commit comments

Comments
 (0)