2

我正在尝试使用 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>
4

2 回答 2

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
于 2011-04-11T18:01:33.553 回答
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散列值作为练习留给读者;)

于 2011-02-23T21:19:54.360 回答