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

allow setting and deleting of attributes on supported XML::Node types #3902

Merged
merged 2 commits into from Mar 13, 2017

Conversation

bmmcginty
Copy link
Contributor

Allow node[name]=value and node.attributes.delete(name)

I'm not sure if Attributes#delete is the correct place for the delete method, but I'm open to suggestions. Maybe Node#delete_attribute?
Also, are we avoiding all methods in libxml2 that require the LIBXML_TREE_ENABLED define? (I've continued that pattern in this PR.)
That should probably be noted somewhere if so.

@asterite
Copy link
Member

Thank you for this!

I initially wrote the libxml2 bindings and I mainly focused on parsing XML, not so much in modifying it afterwards. So that the code is not using functions that depend on LIBXML_TREE_ENABLED is just a coincidence. I would guess that flag is true by default in most systems, so don't hesitate to use any kind of function from libxml2.

Some comments:

  • What do you think if we make node["attr"] = nil remove the attribute? It seems reasonable to me, and that way one can pass a value that could be String or Nil and have the attribute set or removed based on that.
  • I wouldn't raise an exception when trying to delete an attribute that doesn't exist, just like deleting a key from a Hash, when the key doesn't exist, doesn't raise

def []=(name : String, value : String)
curr = self[name]?
if curr
curr.not_nil!.content = value
Copy link
Member

Choose a reason for hiding this comment

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

This not_nil! is not needed because you already checked that it's not nil with if curr above

@bmmcginty
Copy link
Contributor Author

bmmcginty commented Jan 16, 2017

No more raising and Node[attr]=nil now deletes.
f

@asterite
Copy link
Member

Hi @bmmcginty ,

Sorry for what I'm going to say, but we had a discussion about this with @bcardiff and @spalladino and we finally decided that:

  • node[name] = value could look really weird if value might be nil and the attribute is deleted, because that looks like an assignment (for example doing that in a Hash will always insert that key/value pair)
  • node.delete(name) and attributes.delete(name) is better than the above
  • restrict the []= method to only accept String as value (like the code you proposed, but without the Nil overload I proposed)

In Nokogiri you can assign any type as the value, for example 1 or nil, and it ends up converting that value to string and assigning it. But it's a bit weird to do node[name] = nil and then having node[name] be the empty string, so we are not sure about copying that behaviour. If you want you can open an issue to discuss that, but it's low priority.

In short... could you revert your commits to your original proposal? 😊

Thank you!

@bmmcginty
Copy link
Contributor Author

No problem. That completely makes sense.

@bmmcginty
Copy link
Contributor Author

Fixed. []=(string,nil) removed. node.delete calls attributes.delete. attributes.delete deletes attribute if exists, and returns the nodes content or nil if non-existing attribute.

src/xml/node.cr Outdated
@@ -522,4 +534,4 @@ struct XML::Node
ptr = @node.value._private
ptr ? (ptr.as(Array(XML::Error))) : nil
end
end
end
Copy link
Contributor

Choose a reason for hiding this comment

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

No newline at the end of file.

@bmmcginty
Copy link
Contributor Author

@Sija added blank line. travis builds seem to be timing out, though I don't have a Mac to test on.

@RX14
Copy link
Contributor

RX14 commented Feb 1, 2017

@bmmcginty the linux builds are failing due to a formatter error. I think the mac builds died due to a travis incident.

@Sija
Copy link
Contributor

Sija commented Feb 1, 2017

@bmmcginty I'd suggest running crystal format to have it all fixed in one go.

@bmmcginty
Copy link
Contributor Author

@Sija Format has been run and code rebased. Error appears to be just that odd mac one on Travis. Thanks for your patience.

@RX14
Copy link
Contributor

RX14 commented Feb 5, 2017

@bmmcginty CI on OSX has been fixed on master, if you rebase your PR onto master it should be fixed.

@bmmcginty
Copy link
Contributor Author

@RX14 rebased, pushed, and passed. thanks.

src/xml/node.cr Outdated
# Returns `nil` if attribute is not found.
def []?(attribute : String) : String?
attributes[attribute]?.try &.content
end

# sets *attribute* of this node to *value*. Raises `XML::Error` if this node does not support attributes.
Copy link
Contributor

Choose a reason for hiding this comment

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

sets -> Sets

Copy link
Contributor

Choose a reason for hiding this comment

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

Double newline before 2nd sentence would do good.

@@ -21,19 +21,29 @@ struct XML::Node
end

# Gets the attribute content for the *attribute* given by name.
#
Copy link
Contributor

Choose a reason for hiding this comment

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

what's the reason for removal?

# Raises `KeyError` if attribute is not found.
def [](attribute : String) : String
attributes[attribute].content || raise(KeyError.new("Missing attribute: #{attribute}"))
end

# Gets the attribute content for the *attribute* given by name.
#
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

end

# Deletes attribute given by *name*.
# Returns attributes value, or `nil` if attribute not found.
Copy link
Contributor

Choose a reason for hiding this comment

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

Extra newline in between would do good. See previous comments.

Copy link
Member

Choose a reason for hiding this comment

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

@Sija there is no consistency regarding if the docs for the returned / raised should be in a new paragraph. Applying your proposed changes will left xml/node docs inconsistent.

Let's merge this as it is and unify formatting later. I agree a new line looks better in the html rendering but in an .cr file I would probably forgot to include it.

@bcardiff bcardiff merged commit f1a1adb into crystal-lang:master Mar 13, 2017
@bcardiff bcardiff added this to the Next milestone Mar 13, 2017
@bcardiff
Copy link
Member

Thanks @bmmcginty

@joenas
Copy link
Contributor

joenas commented Oct 3, 2018

Is it just me or has there never been a XML::Attributes#delete?

require "xml"
xml = XML.parse("<div></div>")
xml.delete("test")
=> undefined method 'delete' for XML::Attributes

@RX14
Copy link
Contributor

RX14 commented Oct 3, 2018

@joenas looks like a bug, can you report it?

@asterite
Copy link
Member

asterite commented Oct 3, 2018

There's unlink

@joenas
Copy link
Contributor

joenas commented Oct 3, 2018

@RX14 absolutely, issue here or elsewhere?

@bcardiff
Copy link
Member

bcardiff commented Oct 3, 2018

@joenas either open a new issue or, if you have time, a PR fixing it with specs. Thanks!

@joenas
Copy link
Contributor

joenas commented Oct 3, 2018

I’ll see what I can do :) spending most of my free time porting readability to crystal atm

@bmmcginty
Copy link
Contributor Author

bmmcginty commented Oct 3, 2018 via email

@joenas
Copy link
Contributor

joenas commented Oct 4, 2018

@bmmcginty Sorry I just saw this, I'm i CET so... anyways I haven't so feel free!

@joenas
Copy link
Contributor

joenas commented Oct 4, 2018

@bmmcginty Actually I need this to get my readability port working and it looks like I managed to figure it out... so I could put up a PR if you like

@bmmcginty
Copy link
Contributor Author

bmmcginty commented Oct 4, 2018 via email

@joenas
Copy link
Contributor

joenas commented Oct 4, 2018

Done: #6910

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

Successfully merging this pull request may close these issues.

None yet

7 participants