savonrb / nori

XML to Hash translator

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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::StringWithAttributes 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.

Thanks for the update @jeroenj! Given that, I'm inclined to close this since there's a path forward to make this work. How do you feel about that @gnilrets, given that you originally opened this issue?

That's fine @tjarratt. I'm not using 2.2 yet but I do have a workaround in place now.