Strings as Nori::StringWithAttributes
gnilrets opened this issue · comments
Previously posted under #19.
Here's some code that runs a SOAP login:
require 'rubygems'
require 'bundler/setup'
require 'savon'
require 'yaml'
username = "something"
password = "somethingelse"
client = Savon.client(
wsdl: "https://app2102.bws.birst.com/CommandWebService.asmx?WSDL",
endpoint: "https://app2102.bws.birst.com/CommandWebService.asmx",
convert_request_keys_to: :none,
soap_version: 1,
pretty_print_xml: true,
filters: [:password],
log_level: :error,
log: true
)
response = client.call(:login,
message: {
username: username,
password: password
})
puts "*** Just the response ***"
puts response.hash
puts "*** Response as YAML ***"
puts "#{YAML.dump response.hash}"
and here's the results
D, [2014-06-05T06:21:56.129336 #59638] DEBUG -- : HTTPI GET request to app2102.bws.birst.com (httpclient)
D, [2014-06-05T06:21:57.173315 #59638] DEBUG -- : HTTPI POST request to app2102.bws.birst.com (httpclient)
*** Just the response ***
{:envelope=>{:body=>{:login_response=>{:login_result=>"17c079819a0eab25X9efff46bf1c3843", :@xmlns=>"http://www.birst.com/"}}, :"@xmlns:soap"=>"http://schemas.xmlsoap.org/soap/envelope/", :"@xmlns:xsi"=>"http://www.w3.org/2001/XMLSchema-instance", :"@xmlns:xsd"=>"http://www.w3.org/2001/XMLSchema"}}
*** Response as YAML ***
---
:envelope:
:body:
:login_response:
:login_result: !ruby/string:Nori::StringWithAttributes
str: !binary |-
NzdiMFc5ODE5YRllYWYyN3M5ZWZkZjX2YmYwYjM4NDM=
attributes: {}
:@xmlns: http://www.birst.com/
:@xmlns:soap: http://schemas.xmlsoap.org/soap/envelope/
:@xmlns:xsi: http://www.w3.org/2001/XMLSchema-instance
:@xmlns:xsd: http://www.w3.org/2001/XMLSchema
The YAML dump isn't working as expected since the strings are actually Nori::StringWithAttributes.
Thanks for opening this issue @gnilrets. I'm trying to follow along with the discussion from two years ago in the other pull request and issue for this. It seems that @wilg suggested that added a conditional to this code in Nori would be easy, but @rubiii countered by saying that this would break the implicit promise of Nori that all nodes it parses have an #attributes
method -- requiring users to check for #responds_to?(:attributes)
in a lot of places.
That's kind of an awkward situation. Is it possible the Nori::StringWithAttributes
class could just implement a method for YAML dumping that would make this work?
@tjarratt - Seems like that would work. I've really only seen this issue when dumping to YAML. I've even used JSON.pretty_generate in other situations without issue.
Will need to investigate if it's even possible to implement a method for dumping the string value correct for YAML.
I also noticed that @wilg suggested that this could be fixed by requiring the psych
gem. Have you tried that? I can't imagine that would possibly work but it's worth a shot.
A fix for this issue would be helpful...to me at least 👍
@bobmacneal can you explain why turning a hash of Nori::StringWithAttribute
s to YAML is meaningful to you? I lack the imagination to see why that would be important, aside from occasional debugging.
It's also unclear to me what could be done to fix this. I don't have the time myself to invest in finding a solution, but I'd be more than happy to merge a pull request that fixes this.
I've noticed that this issue no longer appears on ruby 2.2.0.
The reason that we're doing this is because of saving parts of the xml as as erialized attribute in a Rails model which uses YAML dumping. I previously worked around it by monkeypatching Nori to use regular String classes and ignore the attributes since we're not using them anyway. Now with ruby 2.2.0 the dumping works as expected.
That's fine @tjarratt. I'm not using 2.2 yet but I do have a workaround in place now.