I am attempting to access a SOAP service using the Ruby gem Savon. I can connect to the service and make a request and receive the response, but I cannot parse the response.
The response contains multiple href references to multiRef elements. When I try to decode it using
response.to_hash[:get_user_risk_profile_response][:get_user_risk_profile_return][:href]
I get #id0. How do I follow the id0 reference?
The SOAP response is below. Thanks!
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<getUserStatusResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<getUserStatusReturn href="#id0"/>
</getUserStatusResponse>
<multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns1:UserRiskProfileBean" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://xrisk.api.example.com">
<parameters xsi:type="ns2:ArrayOf_tns3_ParamBean" xsi:nil="true" xmlns:ns2="http://api.example.com"/>
<siteID xsi:type="soapenc:string">UNKNOWN</siteID>
<userID xsi:type="soapenc:string">sam.wiggins</userID>
<userRiskScore href="#id1"/>
<userRiskScoreDT xsi:type="xsd:dateTime">2011-02-16T18:15:50.012Z</userRiskScoreDT>
</multiRef>
<multiRef id="id1" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:int" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">640</multiRef>
</soapenv:Body>
</soapenv:Envelope>
It seems that the best approach, for the moment, was to just roll my own parsing using XPath. It's crude and probably not very bullet proof, but will do the job until something better comes along.
class SavonResponseXMLParser
def initialize(response_xml)
@doc = REXML::Document.new(response_xml)
end
def get_property(property)
property_value = nil
elements = REXML::XPath.match(@doc, "//#{property}")
if (elements.length == 1)
element = elements[0]
href = element.attributes['href']
if (href)
href =~ /^#id(\d+)/
multiref_elements = REXML::XPath.match(@doc,"//multiRef[@id='id#{$1}']")
if (multiref_elements.length == 1)
multiref_element = multiref_elements[0]
property_value = multiref_element.text
end
else
property_value = element.text
end
end
return property_value
end
end