Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Attribute Functions for the SteamReader #90

Merged
merged 25 commits into from
Sep 1, 2018

Conversation

programmeroftheeve
Copy link
Contributor

@programmeroftheeve programmeroftheeve commented Aug 28, 2018

Adds functions for accessing attributes with the StreamReader without having to expand the tree.

Features:

  • Getting Values from the XML Events (Attributes don't have content, they have values)
    • hasnodevalue
    • nodevalue
  • Getting Attributes with "name" or numeric index
  • Getting a Julia Dictionary of the attribute names and values
  • Added AttributeReader Iterator
  • Get Number of Attributes
  • Check if Attributes Exist

Todo:

  • Add Documentation

@codecov-io
Copy link

codecov-io commented Aug 28, 2018

Codecov Report

Merging #90 into master will increase coverage by 0.11%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #90      +/-   ##
==========================================
+ Coverage   98.89%   99.01%   +0.11%     
==========================================
  Files           7        7              
  Lines         545      608      +63     
==========================================
+ Hits          539      602      +63     
  Misses          6        6
Impacted Files Coverage Δ
src/EzXML.jl 100% <ø> (ø) ⬆️
src/streamreader.jl 98.66% <100%> (+1.1%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3751fbe...360dfb6. Read the comment docs.

Copy link
Member

@bicycle1885 bicycle1885 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I really appreciate your work, but it still need some minor modifications as I commented.

@@ -43,6 +43,7 @@ else
@assert false "invalid Cint size"
end


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This blank line is no needed.

@@ -55,6 +56,8 @@ function Base.convert(::Type{T}, x::ReaderType) where {T<:Integer}
return convert(T, reinterpret(Cint, x))
end

Base.hash(x::ReaderType) = hash(convert(Cint,x))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should implement the two-argument hash method (i.e. hash(x::ReaderType, h::UInt)); see the docstring of hash.

@@ -279,6 +324,8 @@ end
nodecontent(reader::StreamReader)

Return the content of the current node of `reader`.

Note: Nodes of `READER_ATTRIBUTE` will crash with `nodecontent`, use `nodevalue` instead.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can we reach an attribute node while reading an XML doc? Or, do we really need to notify users of this case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An attribute node can be reached with the eachattribute function called on a StreamReader. If need, there can be an ArgumentError thrown when this is called on a attribute node

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But eachattribute returns an AttributeReader object, no?

Anyway, I think throwing an ArgumentError exception would be better than crashing the process.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is true

Cint,
(Ptr{Cvoid},),
reader.ptr)
return r == 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Asserting that r is non-negative (@assert r >= 0) would be nice.

(Ptr{Cvoid},),
reader.ptr)
if value_ptr == C_NULL
return nothing
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, it should throw an ArgumentError exception like other accessor functions. We may change this behavior in the future, but I think we should adhere to consistency for now.

"""
nodeattributecount(reader::StreamReader)

Return a AttributeReader for the current node of `reader`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a AttributeReader => an `AttributeReader`


Return the number of attributes in the current node of `reader`.
"""
function nodeattributecount(reader::StreamReader)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overloading the countattributes function defined in src/node.jl would be better.

test/runtests.jl Outdated
"""))
for typ in reader
if typ == EzXML.READER_ELEMENT
if EzXML.nodename(reader) == "a"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not prefix exported names so that we can check names are surely exported.

return attrs
end

function _getattr(reader::StreamReader, name::AbstractString)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would name it attribute_ptr since I don't start function names with underscore.

src/streamreader.jl Show resolved Hide resolved
test/runtests.jl Outdated
@test hasnodeattributes(reader)
@test countattributes(reader) == 2
@test nodeattributes(reader) == Dict{String,String}("attr1"=>"", "attr2"=>"This is cool")
@test reader[0] == ""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think 1-based indexing is less confusing to most Julians. 0-based indexing is an implementation detail of libxml2 and it shouldn't be exposed to users.

test/runtests.jl Outdated
@test nodevalue(attr) == "This is cool"
end
end
elseif EzXML.nodename(reader) == "b"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EzXML. is unnecessary here.

@@ -82,6 +84,48 @@ const READER_END_ELEMENT = ReaderType(15)
const READER_END_ENTITY = ReaderType(16)
const READER_XML_DECLARATION = ReaderType(17)

function Base.convert(::Type{Symbol},x::ReaderType)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this conversion method? I'm not sure when we want this.

mutable struct AttributeReader
reader::StreamReader

function AttributeReader(reader::EzXML.StreamReader)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You still leave unnecessary EzXML. prefixes in several places.

test/runtests.jl Outdated
@test t == i
@test occursin(r"READER_[A-Z_]+$", repr(t))
@test string(t) == string(i)
@test convert(EzXML.ReaderType, t) === t
end
@test_throws AssertionError repr(convert(EzXML.ReaderType, -1))
@test_throws AssertionError repr(convert(EzXML.ReaderType, 18))
@test_throws AssertionError convert(Symbol, EzXML.ReaderType(18))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this won't pass. Also, please delete unnecessary blank lines above.

@bicycle1885 bicycle1885 merged commit 4e3f059 into JuliaIO:master Sep 1, 2018
@bicycle1885
Copy link
Member

The CI failures on 32-bit Windows would be noise. Thank you for your great pull request!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants