Skip to content

Commit

Permalink
Merge pull request #101 from aminya/DictSupport
Browse files Browse the repository at this point in the history
Dict support
  • Loading branch information
aminya authored Feb 28, 2020
2 parents 3223342 + d5e8e78 commit 8ce7e67
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 179 deletions.
1 change: 1 addition & 0 deletions src/xmlutils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ include("xmlutils/aml_type_support.jl")
################################################################
include("xmlutils/initializer.jl")
include("xmlutils/creators.jl")
include("xmlutils/extractor_utils.jl")
include("xmlutils/extractors.jl")
include("xmlutils/updaters.jl")
################################################################
Empty file.
26 changes: 19 additions & 7 deletions src/xmlutils/creators.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function addelm!(aml::Node, indexstr::String, value::T, argAmlType::Type{AbsText
end
end

# Defined
# Other
function addelm!(aml::Node, name::String, value::T, argAmlType::Type{<:AbsNormal}) where {T}
if hasfield(T, :aml)
link!(aml,value.aml)
Expand Down Expand Up @@ -172,23 +172,35 @@ function addelm!(aml::Node, indexstr::String, value::T, argAmlType::Type{AbsText
end
end


# Nothing
@transform function addelm!(aml::Node, name::String, value::Nothing, argAmlType::Type{allsubtypes(AbsDocOrNode)})
# do nothing
end
################################################################

# Vector

allsubtypes_butAbsText(t) = setdiff(allsubtypes(AbsDocOrNode), [AbsText])

@transform function addelm!(aml::Node, name::String, value::Vector, argAmlType::Type{allsubtypes_butAbsText(AbsDocOrNode)})
foreach(x-> addelm!(aml, name, x, argAmlType), value)
@transform function addelm!(aml::Node, name::String, values::Vector, argAmlType::Type{allsubtypes_butAbsText(AbsDocOrNode)})
foreach(x-> addelm!(aml, name, x, argAmlType), values)
end

function addelm!(aml::Node, indicesstr::String, value::Vector, argAmlType::Type{AbsText})
function addelm!(aml::Node, indicesstr::String, values::Vector, argAmlType::Type{AbsText})
indices = parse_textindices(indicesstr)
if indices isa Colon
indices = 1:length(elements(aml))
end
foreach((x, i)-> addelm!(aml, string(i), x, argAmlType), zip(value, indices))
foreach((x, i)-> addelm!(aml, string(i), x, argAmlType), zip(values, indices))
end

################################################################
# Dict

@transform function addelm!(aml::Node, name::String, values::AbstractDict, argAmlType::Type{allsubtypes(AbsDocOrNode)})
# name is discarded now: actual names are stored in the Dict itself
# elements are added directly
# for AbsText, v_name is considered as the text index
for (v_name, v_value) in values
addelm!(aml, v_name, v_value, argAmlType)
end
end
172 changes: 172 additions & 0 deletions src/xmlutils/extractor_utils.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
export findalllocal, findfirstlocal, findtext, findtextloacl, findvecttextlocal
################################################################
# Searchers Utils
################################################################
# Local searchers (no namespace)
"""
findfirstlocal(string, node)
findfirst with ignoring namespaces. It considers element.name for returning the elements
Much faster than EzXML.findfirst
"""
function findfirstlocal(name::String, node::Node)
out = nothing # return nothing if nothing is found
for child in eachelement(node)
if child.name == name
out = child
break
end
end
return out
end

"""
findalllocal(string, node)
findalllocal with ignoring namespaces. It considers element.name for returning the elements
Much faster than EzXML.findall
"""
function findalllocal(name::String, node::Node)
out = Node[]
for child in eachelement(node)
if child.name == name
push!(out, child)
end
end
if !isempty(out)
return out
else # return nothing if nothing is found
return nothing
end
end

function findtext(indexstr::String, node::Node)
if indexstr == ""
index = 1
else
index = eval(Meta.parse(indexstr))
end
xpath = "text()[position() = $index]"
out = findfirst(xpath, node)
return out
end

# function findvecttext(indexstr::String, node::Node)
# if indexstr == ""
# index = Colon()
# else
# index = eval(Meta.parse(indexstr))
# end
# xpath = "text()"
# out = findfirst(xpath, node)
# return out
# end

"""
parse_textindex(indexstr::String)
Index is a String of an Integer e.g. "2". If indexstr is empty (`""`) it returns the first one found.
"""
function parse_textindex(indexstr::String)
if indexstr == ""
index = 1
elseif indexstr == "end"
index = Inf
else
indexExpr = Meta.parse(indexstr)
indexExpr isa Integer || error("give index as an Integer e.g. \"2\"")
index = eval(indexExpr)
end
return index
end

"""
findtextlocal(index::Integer, node)
finds the text node at position given by index.
faster than `findtext()`
"""
function findtextlocal(index::Integer, node::Node)
iText = 0
out = nothing # return nothing if nothing is found
for child in eachnode(node)
if istext(child)
iText +=1
if iText == index
out = child
break
end
end
end
return out
end
function findtextlocal(index::Float64, node::Node)
if index != Inf
error("index should be \"end\"")
end
out = nothing # return nothing if nothing is found
for child in eachnode(node)
if istext(child)
out = child
end
end
return out
end

"""
parse_textindices(indicesstr::String)
Index is a String of an Integer e.g. "2". If indicesstr is empty (`""`) it returns the all of the text nodes.
"""
function parse_textindices(indicesstr::String)
if indicesstr == ""
indices = Colon()
else
indicesExpr = Meta.parse(indicesstr)
indicesExpr.head == :vect || error("give indices as a vetor e.g. [2:3], [2, 3] ,[:]")
indices = eval(indexExpr)
end
return indices
end

"""
findvecttextlocal(indices, node)
finds the text node at positions given by indices.
faster than `findvecttext()`
"""
function findvecttextlocal(indices::Colon, node::Node)
out = Node[]
for child in eachnode(node)
if istext(child)
push!(out, child)
end
end
if !isempty(out)
return out
else # return nothing if nothing is found
return nothing
end
end

function findvecttextlocal(indices::AbstractVector, node::Node)
out = Node[]
iText = 0
for child in eachnode(node)
if istext(child)
iText +=1
if iText in indices
push!(out, child)
end
end
end
if !isempty(out)
return out
else # return nothing if nothing is found
return nothing
end
end
Loading

0 comments on commit 8ce7e67

Please sign in to comment.