我试图使用Ruby gem Savon访问SOAP服务。我可以连接到服务并发出请求并收到响应,但我无法解析响应。
响应包含对multiRef元素的多个href引用。当我尝试使用
解码它时response.to_hash[:get_user_risk_profile_response][:get_user_risk_profile_return][:href]
我得#id0。我如何遵循id0参考?
SOAP响应如下。谢谢!
<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>
答案 0 :(得分:1)
目前看来,最好的方法是使用XPath进行自己的解析。这是原始的,可能不是非常防弹,但会做好工作直到更好的事情出现。
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
答案 1 :(得分:0)
您必须手动解决参考:
id = response.to_hash[:get_user_risk_profile_response][:get_user_risk_profile_return][:href]
references = response.to_hash[:multi_ref]
result = references.select {|ref| ref[:id] == id.sub('#', '') }
我建议将上面的内容放在辅助方法/模块中:
module MultiRef
def resolve_ref(id)
references = to_hash[:multi_ref]
references.select {|ref| ref[:id] == id.sub('#', '') }
end
end
Savon::Response.send(:include, MultiRef)
然后只需:
response.resolve_ref("#id1")
以适当的引用值递归替换href
哈希值作为练习留给读者;)