ruby - 从 XML 转换为 REST 客户端以进行 POST 请求

标签 ruby xml rest-client

为了接收响应,我必须通过 POST 发出 XML 请求:

<BackgroundCheck userId="username" password="password">
  <BackgroundSearchPackage action="submit" type="demo product">
    <ReferenceId>some_id_value</ReferenceId>
    <PersonalData>
      <PersonName>
        <GivenName>John</GivenName>  
        <MiddleName>Q</MiddleName>
        <FamilyName>Test</FamilyName>
      </PersonName>
      <Aliases>
        <PersonName>
          <GivenName>Jack</GivenName>
          <MiddleName>Quigley</MiddleName>
          <FamilyName>Example</FamilyName>
        </PersonName>
      </Aliases>
      <DemographicDetail>
        <GovernmentId issuingAuthority="SSN">123456789</GovernmentId>
        <DateOfBirth>1973-12-25</DateOfBirth>
      </DemographicDetail>
      <PostalAddress>
        <PostalCode>83201</PostalCode>
        <Region>UT</Region>
        <Municipality>Salt Lake City</Municipality>
        <DeliveryAddress>
          <AddressLine>1234</AddressLine>
          <StreetName>Main Street</StreetName>
        </DeliveryAddress>
      </PostalAddress>
      <EmailAddress><a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="503a3f383e10243523247e333f3d" rel="noreferrer noopener nofollow">[email protected]</a></EmailAddress>
      <Telephone>801-789-4229</Telephone>
    </PersonalData>
  </BackgroundCheck>
</BackgroundSearchPackage>

使用 rest-client github page 上的示例,我使用 Rest-client 提出了以下翻译:

response = RestClient.post( 'url',
  {
    :BackgroundCheck => {
      :userID => 'username',
      :password => 'password',
    }, 
    :BackgroundSearchPackage => {
      :action => 'submit',
      :type => 'demo'
    }, 
    :ReferenceID => 'some_id_value', 
    :PersonalData => {
      :PersonalName => {
        :GivenName => 'John',
        :MiddleName => 'Q',
        :FamilyName => 'Test'
      }, 
       :Aliases => {
        :GivenName => 'Jack',
        :MiddleName => 'Quigly',
        :FamilyName => 'Example'
      }
    }, 
    :DemographicDetail => {
      :GovernmentId => {
        :issuingAuthority => "SSN"
      },  ## where do I enter the SSN?
      :DateOfBirth => '1972-12-25'
    }, 
    :PostalAddress => {
      :PostalCode => '83201',
      :Region => 'UT',
      :Municipality => 'Salt Lake City',
      :DeliveryAddress => {
        :AddressLine => '1234',
        :StreetName => 'Main Street'
      }
    }, 
    :EmailAddress => '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0f656067614f7b6a7c7b216c6062" rel="noreferrer noopener nofollow">[email protected]</a>', 
    :Telephone => '801-789-4229'
  })

这是我第一次使用 XML 和 Rest-client gem。

我的问题是我是否正确翻译了 POST 请求中的 XML?

更具体地说,我如何处理 GovernmentID 并引用 SSN 条目?

最佳答案

首先,您提供的 XML 无效!您的根元素以 BackgroundCheck 开头,以 BackgroundSearchPackage 结尾:

<BackgroundCheck userId="username" password="password">
  <BackgroundSearchPackage action="submit" type="demo product">
  </BackgroundCheck>
</BackgroundSearchPackage>

此外,您从 XML 到 Ruby 哈希的翻译/转换不正确。如果 BackgroundCheck 是您的根元素,而 BackgroundSearchPackage 是它的子元素,您的 Ruby 哈希值应如下所示(rest-client 接受字符串和符号表示法):

my_xml_hash = {
  "BackgroundCheck" => {
    "userId"=>"username",
    "password"=>"password",
    "BackgroundSearchPackage" => {
      "action"=>"submit",
      "type"=>"demo product",
      ...
      "PersonalData" => { ... },
      ...
    }
  }
}

您可以像这样访问 Ruby 哈希中的值:

# string syntax
my_xml_hash['BackgroundCheck']['BackgroundSearchPackage']['PersonalData']['DemographicDetail']['GovernmentId']
 => "123456789"

# symbol syntax
other_xml_hash[:BackgroundCheck][:BackgroundSearchPackage][:PersonalData][:DemographicDetail]['GovernmentId']
 => "123456789"



如果我理解正确的话,您想通过 POST 请求发送 XML。但是如果您使用哈希语法,您将无法实现您可能想要的结果,因为 rest-client 会将您的数据作为参数而不是 XML 数据发布!

如果您只需要调整GovernmentIDissuingAuthority,我会按如下方式进行。

require 'rest_client'

# the customized 'GovernmentID'
government_id = '123'

# the customized 'issuingAuthority'
issuing_authority = 'FOO'

xml_template =<<END_OF_XML
  <BackgroundCheck userId="username" password="password">
    <BackgroundSearchPackage action="submit" type="demo product">
      <ReferenceId>some_id_value</ReferenceId>
      <PersonalData>
        <PersonName>
          <GivenName>John</GivenName>  
          <MiddleName>Q</MiddleName>
          <FamilyName>Test</FamilyName>
        </PersonName>
        <Aliases>
          <PersonName>
            <GivenName>Jack</GivenName>
            <MiddleName>Quigley</MiddleName>
            <FamilyName>Example</FamilyName>
          </PersonName>
        </Aliases>
        <DemographicDetail>
          <GovernmentId issuingAuthority="#{issuing_authority}">#{government_id}</GovernmentId>
          <DateOfBirth>1973-12-25</DateOfBirth>
        </DemographicDetail>
        <PostalAddress>
          <PostalCode>83201</PostalCode>
          <Region>UT</Region>
          <Municipality>Salt Lake City</Municipality>
          <DeliveryAddress>
            <AddressLine>1234</AddressLine>
            <StreetName>Main Street</StreetName>
          </DeliveryAddress>
        </PostalAddress>
        <EmailAddress><a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="503a3f383e10243523247e333f3d" rel="noreferrer noopener nofollow">[email protected]</a></EmailAddress>
        <Telephone>801-789-4229</Telephone>
      </PersonalData>
    </BackgroundSearchPackage>
  </BackgroundCheck>
END_OF_XML

# Go to http://requestb.in/ , click on "Create a RequestBin", copy the "Bin URL" and use it for your tests ;-)
response = RestClient.post('http://your.target.tld/your/webservice', xml_template, { content_type: :xml })

puts "Response: #{response.inspect}"



REXML 示例:

require 'rest_client'
require 'rexml/document'

xml_string =<<END_OF_XML
  <BackgroundCheck userId="username" password="password">
    <BackgroundSearchPackage action="submit" type="demo product">
      <ReferenceId>some_id_value</ReferenceId>
      <PersonalData>
        <PersonName>
          <GivenName>John</GivenName>  
          <MiddleName>Q</MiddleName>
          <FamilyName>Test</FamilyName>
        </PersonName>
        <Aliases>
          <PersonName>
            <GivenName>Jack</GivenName>
            <MiddleName>Quigley</MiddleName>
            <FamilyName>Example</FamilyName>
          </PersonName>
        </Aliases>
        <DemographicDetail>
          <GovernmentId issuingAuthority="SSN">123456789</GovernmentId>
          <DateOfBirth>1973-12-25</DateOfBirth>
        </DemographicDetail>
        <PostalAddress>
          <PostalCode>83201</PostalCode>
          <Region>UT</Region>
          <Municipality>Salt Lake City</Municipality>
          <DeliveryAddress>
            <AddressLine>1234</AddressLine>
            <StreetName>Main Street</StreetName>
          </DeliveryAddress>
        </PostalAddress>
        <EmailAddress><a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="177d787f7957637264633974787a" rel="noreferrer noopener nofollow">[email protected]</a></EmailAddress>
        <Telephone>801-789-4229</Telephone>
      </PersonalData>
    </BackgroundSearchPackage>
  </BackgroundCheck>
END_OF_XML

# Build XML document from string
doc = REXML::Document.new(xml_string)
government_element = REXML::XPath.first(doc, "//GovernmentId")

# Read values:
puts government_element.text
puts government_element.attributes['issuingAuthority']
# OR directly via XPath
puts REXML::XPath.first(doc, "//GovernmentId").text
puts REXML::XPath.first(doc, "//GovernmentId/@issuingAuthority").value

# Write values: 
government_element.text = 'my new text value'
government_element.attributes['issuingAuthority'] = 'my new attribute value'

# Go to http://requestb.in/ , click on "Create a RequestBin", copy the "Bin URL" and use it for your tests ;-)
response = RestClient.post('http://your.target.tld/your/webservice', doc.to_s, { content_type: :xml })

puts "Response: #{response.inspect}"



如果您需要编写复杂的 XML 树,我建议您查看以下精华:

或者使用像 ERB 这样的模板引擎来简化它。

关于ruby - 从 XML 转换为 REST 客户端以进行 POST 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26874605/

相关文章:

ruby-on-rails - 突然ArgumentError : invalid byte sequence in UTF-8 while seeding

php - 将 XML 数据加载到 MYSQL(MYSQL 版本 5.1)

xml - 如何从输出 xml 中删除 namespace ?

带有 cookie 的 Ruby RestClient 发布请求

ruby-on-rails - 在同一个数据库上工作的多个工作线程 - 如何使其正常工作?

javascript - 将 collection_select 菜单选项链接到过滤方法 - Ruby on Rails

ruby - double 和 spy 和有什么不一样?

java - Java 中的 XML 解析和 DOM 管理

ruby - 如何查看来自 HTTParty get 请求的响应 cookie?

android - 正确的 Android REST 客户端