Simple XML.write followed by XML.parse fails
I expected this to work but it doesn't. Maybe I shouldn't expect it to?
julia> using XML
julia> doc = XML.Document()
Node (depth=1) Document
julia> dec = XML.Declaration(; var"xml version"="1.0", encoding="UTF-8")
Node (depth=1) Declaration <?xml xml version="1.0" encoding="UTF-8"?>
julia> test = XML.Element("test")
Node (depth=1) Element <test>
julia> push!(doc, dec)
1-element Vector{Node}:
Node (depth=1) Declaration <?xml xml version="1.0" encoding="UTF-8"?>
julia> push!(doc, test)
2-element Vector{Node}:
Node (depth=1) Declaration <?xml xml version="1.0" encoding="UTF-8"?>
Node (depth=1) Element <test>
julia> XML.nodetype(doc) == XML.Document
true
julia> doc == XML.parse(XML.Node, XML.write(doc))
ERROR: MethodError: no method matching isless(::Int64, ::Nothing)
The function `isless` exists, but no method is defined for this combination of argument types.
Closest candidates are:
isless(::Missing, ::Any)
@ Base missing.jl:87
isless(::Any, ::Missing)
@ Base missing.jl:88
isless(::Real, ::AbstractFloat)
@ Base operators.jl:179
...
Stacktrace:
[1] <(x::Int64, y::Nothing)
@ Base .\operators.jl:353
[2] >(x::Nothing, y::Int64)
@ Base .\operators.jl:379
[3] get_attributes(data::Vector{UInt8}, i::Int64, j::Int64)
@ XML C:\Users\tim\.julia\packages\XML\sVTgr\src\raw.jl:120
[4] attributes(o::XML.Raw)
@ XML C:\Users\tim\.julia\packages\XML\sVTgr\src\raw.jl:164
[5] getproperty(o::LazyNode, x::Symbol)
@ XML C:\Users\tim\.julia\packages\XML\sVTgr\src\XML.jl:82
[6] Node(node::LazyNode)
@ XML C:\Users\tim\.julia\packages\XML\sVTgr\src\XML.jl:163
[7] iterate(g::Base.Generator{Vector{LazyNode}, Type{Node}}, s::Int64)
@ Base .\generator.jl:48
[8] collect_to!(dest::Vector{Node}, itr::Base.Generator{Vector{LazyNode}, Type{Node}}, offs::Int64, st::Int64)
@ Base .\array.jl:849
[9] collect_to_with_first!(dest::Vector{Node}, v1::Node, itr::Base.Generator{Vector{LazyNode}, Type{Node}}, st::Int64)
@ Base .\array.jl:827
[10] _collect(c::Vector{LazyNode}, itr::Base.Generator{Vector{…}, Type{…}}, ::Base.EltypeUnknown, isz::Base.HasShape{1})
@ Base .\array.jl:821
[11] collect_similar(cont::Vector{LazyNode}, itr::Base.Generator{Vector{LazyNode}, Type{Node}})
@ Base .\array.jl:720
[12] map(f::Type, A::Vector{LazyNode})
@ Base .\abstractarray.jl:3371
[13] Node(node::LazyNode)
@ XML C:\Users\tim\.julia\packages\XML\sVTgr\src\XML.jl:166
[14] Node
@ C:\Users\tim\.julia\packages\XML\sVTgr\src\XML.jl:169 [inlined]
[15] parse
@ C:\Users\tim\.julia\packages\XML\sVTgr\src\XML.jl:201 [inlined]
[16] parse(::Type{Node}, str::String)
@ XML C:\Users\tim\.julia\packages\XML\sVTgr\src\XML.jl:290
[17] top-level scope
@ REPL[8]:1
Sorry for leaving this untouched for so long. Parsing is pretty ad-hoc/experimental/not well tested. I have a rewrite in the works that will make it better/well tested but it'll be a few weeks before it's ready.
Just ran a quick check of this in 0.3.8 and made several observations:
dec = XML.Declaration(; var"xml version"="1.0", encoding="UTF-8") is incorrect and should be dec = XML.Declaration(; version="1.0", encoding="UTF-8")
With this change, and using v0.3.8, the test that previously errored no longer does but instead returns false:
julia> doc == XML.parse(XML.Node, XML.write(doc))
false
But this test works:
julia> XML.write(doc)==XML.write(XML.parse(XML.Node, XML.write(doc)))
true
The reason for this seems to be that parse and XML.Element generate different instantiations of (empty) children, in this case children of the <test> element:
julia> doc[2].children
Node[] # produced by XML.Element
julia> doc2=XML.parse(XML.Node, XML.write(doc))
Node Document (2 children)
julia> doc2[2].children
# nothing - produced by parse
julia>
So I think this now boils down to another manifestation of #33 but for children instead of attributes.